home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume23 / trn / part12 < prev    next >
Encoding:
Text File  |  1991-08-22  |  64.5 KB  |  2,553 lines

  1. This is a new archive version of TRN at patchlevel 3.
  2. The original posting took up Volume23, issues 60 to 73, with
  3. various problems.  These files replace those issues.
  4.  
  5. #! /bin/sh
  6. # This is a shell archive.  Remove anything before this line, then feed it
  7. # into a shell via "sh file" or similar.  To overwrite existing files,
  8. # type "sh file -c".
  9. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  10. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  11. # Contents:  MANIFEST HACKERSGUIDE Makefile.SH Rnmail.SH artsrch.c
  12. #   final.c kfile.c rthreads.c uudecode.c
  13. # Wrapped by rsalz@litchi.bbn.com on Fri Aug 23 16:39:02 1991
  14. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  15. echo If this archive is complete, you will see the following message:
  16. echo '          "shar: End of archive 12 (of 14)."'
  17. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  18.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  19. else
  20.   echo shar: Extracting \"'MANIFEST'\" \(5281 characters\)
  21.   sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  22. XAfter unpacking, you should have the following files:
  23. X
  24. XFilename    Description
  25. X--------    -----------
  26. XConfigure       A shell script that installs everything system dependent.
  27. XEXTERN.h        When included, makes other includes not belong to me.
  28. XHACKERSGUIDE    A brief guide to the contorted innards of trn.
  29. XINIT            Sample system-wide switch file.
  30. XINTERN.h        When included, makes other includes belong to me.
  31. XMANIFEST        This list of files.
  32. XMakefile.SH     The makefile.
  33. XNEW             List of new features with trn v1.0.
  34. XPnews.1         Manual page for Pnews.
  35. XPnews.SH        A news posting shell script that knows about -h.
  36. XREADME          Installation instructions and other tidbits.
  37. XRnmail.1        Manual page for Rnmail.
  38. XRnmail.SH       A mailer that knows about -h.
  39. XWishlist        What the next version wants in it.
  40. Xaddng.c         Routines for scanning the active file for new newsgroups.
  41. Xaddng.h         Public info regarding addng.c.
  42. Xart.c           Routines to display an article.
  43. Xart.h           Public info regarding art.c.
  44. Xartio.c         Reserved for the article abstract type, someday.
  45. Xartio.h         Public info regarding artio.c.
  46. Xartsrch.c       Routines for searching among articles.
  47. Xartsrch.h       Public info regarding artsrch.c.
  48. Xartstate.h      Info on the current state of the article.
  49. Xbackpage.c      Routines for paging backwards in articles.
  50. Xbackpage.h      Public info regarding backpage.c.
  51. Xbits.c          Bitmap management functions.
  52. Xbits.h          Public info regarding bits.c.
  53. Xcheat.c         Routines to do lookahead of several types.
  54. Xcheat.h         Public info regarding cheat.c.
  55. Xcommon.h        Global info.
  56. Xfinal.c         Finalization (exit) routines.
  57. Xfinal.h         Public info regarding final.c.
  58. Xgetactive.c     Program used by shell scripts to the active file (trrn only).
  59. Xgetdate.y       A yacc script for date parsing.
  60. Xhead.c          Header parsing routines.
  61. Xhead.h          Public info regarding head.c.
  62. Xhelp.c          Help routines.
  63. Xhelp.h          Public info regarding help.c.
  64. Xinit.c          Initialization (startup) routines.
  65. Xinit.h          Public info regarding init.c.
  66. Xintrp.c         Filename expansion and % interpretation routines.
  67. Xintrp.h         Public info regarding intrp.c.
  68. Xkfile.c         KILL file routines.
  69. Xkfile.h         Public info regarding kfile.c.
  70. Xlast.c          Routines for handling the .rnlast file.
  71. Xlast.h          Public info regarding last.c.
  72. Xmakedepend.SH   Shell script to generate make dependencies.
  73. Xmakedir.SH      Shell script to make nested subdirectories.
  74. Xmbox.saver.SH   Shell script to save an article to a mailbox.
  75. Xmt-lint.h       A kludge file included when lint'ing.
  76. Xmt-process.c    Mthreads' article processing routines.
  77. Xmt-read.c       Mthreads' data-file reading routines.
  78. Xmt-write.c      Mthreads' data-file writing routines.
  79. Xmt.check.SH     A sample mt.log checker/trimmer.
  80. Xmthreads.1      The man page for mthreads.
  81. Xmthreads.c      The main workloop for the mthreads database manager.
  82. Xmthreads.h      The include file for accessing the 'mt' structures.
  83. Xndir.c          4.2 directory routine emulation.
  84. Xndir.h          Public info regarding ndir.c.
  85. Xnewsetup.1      Manual page for newsetup.
  86. Xnewsetup.SH     Shell script to create a .newsrc file.
  87. Xnewsgroups.1    Manual page for newsgroups.
  88. Xnewsgroups.SH   Shell script to list unsubscribed newsgroups.
  89. Xnewsnews.SH     A motd-like file that trn may print at startup.
  90. Xng.c            Routines to display a newsgroup.
  91. Xng.h            Public info regarding ng.c.
  92. Xngdata.c        General data fetching routines for a newsgroup.
  93. Xngdata.h        Public info regarding ngdata.c.
  94. Xngsrch.c        Routines to search among newsgroups.
  95. Xngsrch.h        Public info regarding ngsrch.c.
  96. Xngstuff.c       Support routines for ng.c.
  97. Xngstuff.h       Public info regarding ng.c.
  98. Xnorm.saver.SH   Shell script to save an article to a normal file.
  99. Xonly.c          Routines to perform newsgroup restriction.
  100. Xonly.h          Public info regarding only.c.
  101. Xpatchlevel      Indicates current patch level.
  102. Xrcln.c          Routines to mung a .newsrc line.
  103. Xrcln.h          Public info regarding rcln.c.
  104. Xrcstuff.c       Routines to mung the .newsrc file.
  105. Xrcstuff.h       Public info regarding rcstuff.c.
  106. Xrespond.c       Various routines for doing things with articles.
  107. Xrespond.h       Public info regarding respond.c.
  108. Xrn.c            Main program.
  109. Xrn.h            Public info regarding rn.c.
  110. Xrt-rn.c         Misc. threaded routines.
  111. Xrt-select.c     The thread selector.
  112. Xrthreads.c      Routines that read the thread data files in reader format.
  113. Xrthreads.h      The include file for accessing the 'rt' structures.
  114. Xsearch.c        Regular expression processing ala emacs.
  115. Xsearch.h        Public info regarding search.c.
  116. Xsw.c            Switch processing routines.
  117. Xsw.h            Public info regarding switch.c.
  118. Xterm.c          Terminal interface routines.
  119. Xterm.h          Public info regarding term.c.
  120. Xthreads.c       Routines common to both thread makers and readers.
  121. Xthreads.h       The include file for common thread structures.
  122. Xtrn.1           Manual pages for trn -- PLEASE READ.
  123. Xutil.c          Utility routines.
  124. Xutil.h          Public info regarding util.c.
  125. Xuudecode.c      The uudecoder routines.
  126. Xuudecode.h      The uudecoder's include file.
  127. END_OF_FILE
  128.   if test 5281 -ne `wc -c <'MANIFEST'`; then
  129.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  130.   fi
  131.   # end of 'MANIFEST'
  132. fi
  133. if test -f 'HACKERSGUIDE' -a "${1}" != "-c" ; then 
  134.   echo shar: Will not clobber existing file \"'HACKERSGUIDE'\"
  135. else
  136.   echo shar: Extracting \"'HACKERSGUIDE'\" \(4518 characters\)
  137.   sed "s/^X//" >'HACKERSGUIDE' <<'END_OF_FILE'
  138. XHacking Notes
  139. X
  140. XIf you aren't interested in mucking with the innards of rn, don't read this.
  141. X
  142. XIn the interests of both space and time optimization, things are done inside
  143. Xrn that don't always conform to the highest ideals of programming.  To the
  144. Xextent I felt it was practical, I've tried to conform to good programming
  145. Xpractice, but you must realize that my goal was to make a better mousetrap,
  146. Xso certain conscious tradeoffs were made in the design of rn right from the
  147. Xstart.  In particular, if you want to hack on rn (and I wouldn't blame you,
  148. Xit's fun), beware of the following:
  149. X  
  150. X  * buf and cmd_buf are reused all over the place.  11-squishing is a good
  151. X    term for it.  No, I'm on a Vax now, but I've been there.
  152. X
  153. X  * The article header is parsed on the fly, while it is being displayed.
  154. X    In fact, practically everything is done on the fly within the article
  155. X    display loop, and there are plenty of state variables.  The header
  156. X    is never explicitly stored in memory; rather, pointers are kept into
  157. X    the file.  The information required to backup pages is not stored in
  158. X    memory, except for 1 buffer's worth.  The information required to do
  159. X    the delayed mark as unread (M) is not stored in memory either.
  160. X
  161. X  * Lots of contortions are gone through to avoid using static memory, or
  162. X    allocating unnecessary memory, or losing track of allocated memory,
  163. X    while at the same time allowing .newsrc lines and header lines to be
  164. X    ANY length up to the amount of memory you have.  Rn spends a great deal
  165. X    of effort being lazy.  Do not use a static buffer when you can use
  166. X    growstr().
  167. X
  168. X  * Lots of contortions are gone through to try to do things when people
  169. X    aren't waiting, or have only been waiting a very short time.  Guessing
  170. X    the next article to be opened and opening it, searching ahead for the
  171. X    next article with the same subject, delaying the look up of the number
  172. X    of articles in a newsgroup, writing the rest of the page while the
  173. X    reader is examining the header, cacheing up subjects while the user
  174. X    is reading, checkpointing the .newsrc only while the reader is in the
  175. X    middle of an interesting article, are some of the strategies employed.
  176. X  
  177. X  * There are plenty of goto's.  Most of them involve going back to reprompt,
  178. X    to reask for input, or to just plain do the unstructured things people
  179. X    want to do when they are glaring at a terminal.  If they bother you
  180. X    too much, just think of rn as a big state machine.  If they don't bother
  181. X    you at all, I don't want you hacking on rn.
  182. X
  183. X  * Put all includes at the front of the file, before the first function,
  184. X    or makedepend will not work right.  I could relax this, but makedepend
  185. X    would take about 5 times longer to run.
  186. X
  187. XIn general then, feel free to hack on rn.  Just don't broadcast untested
  188. Xpatches to the net.  Remember that there are people with limited address
  189. Xspaces and limited cpu cycles.  If you add a wonderful new feature and
  190. Xwant to publish a patch, put #ifdef's around it so that people who don't
  191. Xwant it or can't afford it can work around it.  THIS MEANS YOU.  We don't
  192. Xneed 57 varieties of mutually incompatible and incomprehensible rn floating
  193. Xabout the net.  Consider telling me about your patch so that I can consider
  194. Xincluding it in the standard version.  A COMPLETE PATCH TAKES INTO ACCOUNT
  195. XSYSTEM DEPENDENCIES AS DETERMINED BY THE CONFIGURE SCRIPT.
  196. X
  197. X* Don't use ints where rn uses typedefs, in particular, for article numbers.
  198. X* Don't use %d anywhere that someone might need a %ld.  (Just because YOU
  199. X    typedefed it as an int doesn't mean someone else won't need a long.)
  200. X* Don't use %D, that's archaic.
  201. X* Put FLUSHes after printf()s, fputs()es and putchar('\n')s for our poor
  202. X    brethern and sistern without line buffering.
  203. X* Declare the type of every function.  Use void, even if your C compiler
  204. X    doesn't.
  205. X* Follow the style that rn already uses!  This is my pet peeve.  Well, one of
  206. X    them, anyway.  I follow other people's strange styles when modifying
  207. X    their programs, so I'd be much obliged if you did likewise.
  208. X* Use lint.
  209. X* Use RCS.  Start a new branch, like 4.3.[2-9].  (I will use 4.3.1 myself.)
  210. X* Be structured wherever it doesn't interfere with practicality.
  211. X* Long live paranoid programming.  The rest of the program is out to get you.
  212. X    The world is out to destroy the program, not to mention the .newsrc.
  213. X    And then there's always bitrot...
  214. X* Stop reading this lugubrious trash and start thinking for yourself.
  215. X* Thank you and good night.
  216. END_OF_FILE
  217.   if test 4518 -ne `wc -c <'HACKERSGUIDE'`; then
  218.     echo shar: \"'HACKERSGUIDE'\" unpacked with wrong size!
  219.   fi
  220.   # end of 'HACKERSGUIDE'
  221. fi
  222. if test -f 'Makefile.SH' -a "${1}" != "-c" ; then 
  223.   echo shar: Will not clobber existing file \"'Makefile.SH'\"
  224. else
  225.   echo shar: Extracting \"'Makefile.SH'\" \(6240 characters\)
  226.   sed "s/^X//" >'Makefile.SH' <<'END_OF_FILE'
  227. Xcase $CONFIG in
  228. X    '') . ./config.sh ;;
  229. Xesac
  230. Xecho "Extracting Makefile (with variable substitutions)"
  231. Xcat >Makefile <<!GROK!THIS!
  232. X# $Header: makefile.SH,v 4.3.3.2 91/01/16 02:48:10 davison Trn $
  233. X#
  234. X# $Log:    makefile.SH,v $
  235. X# Revision 4.3.3.2  91/01/16  02:48:10  davison
  236. X# Integrated rn patches 48-54.
  237. X# 
  238. X# Revision 4.3.3.1  90/07/28  18:14:56  davison
  239. X# Initial Trn Release
  240. X# 
  241. X# Revision 4.3.2.11  90/11/22  13:57:53  sob
  242. X# Added support for additional CFLAGS and better cleanup.
  243. X# 
  244. X# Revision 4.3.2.10  90/05/04  00:44:51  sob
  245. X# Added socketlib to list of libs.
  246. X# 
  247. X# Revision 4.3.2.9  90/04/23  00:27:12  sob
  248. X# Added better support for XENIX
  249. X# 
  250. X# Revision 4.3.2.8  89/12/20  23:20:14  sob
  251. X# Added "hp-ux" to the list of files created by Configure.
  252. X# 
  253. X# Revision 4.3.2.7  89/12/09  01:49:48  sob
  254. X# make clean cleans up better.
  255. X# 
  256. X# Revision 4.3.2.6  89/12/08  22:43:45  sob
  257. X# Added suggestions by weening@gang-of-four.stanford.edu and 
  258. X# jik@pit-manager.mit.edu. rrn manual page is now created when
  259. X# doing an installation. getactive will only be made when rrn is being
  260. X# created.
  261. X# 
  262. X# Revision 4.3.2.5  89/11/08  04:47:38  sob
  263. X# Added VOIDSIG handling for SunOS 4.X
  264. X# 
  265. X# Revision 4.3.2.4  89/11/08  03:16:29  sob
  266. X# Added server.h to list of things created by Configure
  267. X# 
  268. X# Revision 4.3.2.3  89/11/08  01:05:52  sob
  269. X# Updated to work with RRN or RN
  270. X# 
  271. X# Revision 4.3.2.2  89/11/06  00:03:19  sob
  272. X# Added RRN support originally distributed with NNTP 1.5
  273. X# 
  274. X# Revision 4.3.2.1  89/11/05  23:55:09  sob
  275. X# RRN support branch
  276. X#
  277. X# Revision 4.3.1.2  85/05/13  17:21:18  lwall
  278. X# System V make needs space before line-continuing backslash.
  279. X# 
  280. X# Revision 4.3.1.1  85/05/10  11:30:15  lwall
  281. X# Branch for patches.
  282. X# 
  283. X# Revision 4.3  85/05/01  11:33:26  lwall
  284. X# Baseline for release with 4.3bsd.
  285. X# 
  286. X
  287. XCC = $cc
  288. Xrnbin = $rnbin
  289. Xrnlib = $rnlib
  290. Xmansrc = $mansrc
  291. Xmanext = $manext
  292. X#NNTPNNTPDIR = $NNTPSRC
  293. X#NNTPNNTPINC = $rrninclude
  294. XCFLAGS = $iandd $addcflags -O $include
  295. XLDFLAGS = $iandd
  296. XNDIRC = $ndirc
  297. XNDIRO = $ndiro
  298. X
  299. Xlibs = $ndirlib $termlib $jobslib $socketlib
  300. Xmlibs = $jobslib
  301. X!GROK!THIS!
  302. Xcat >>Makefile <<'!NO!SUBS!'
  303. X#NNTPnntp=getactive
  304. Xpublic = trn newsetup newsgroups Pnews Rnmail
  305. Xprivate = norm.saver mbox.saver makedir\
  306. X    filexp Pnews.header mthreads mt.check $(nntp)
  307. Xmanpages = trn.1 Pnews.1 Rnmail.1 newsetup.1 newsgroups.1 mthreads.1
  308. Xutil = Makefile makedepend newsnews
  309. X
  310. X
  311. Xh1 = addng.h art.h artio.h artsrch.h backpage.h bits.h cheat.h common.h
  312. Xh2 = final.h head.h help.h init.h intrp.h kfile.h last.h ndir.h ng.h
  313. Xh3 = ngdata.h ngsrch.h ngstuff.h only.h rcln.h rcstuff.h
  314. Xh4 = respond.h rn.h search.h sw.h term.h util.h uudecode.h
  315. X#NNTPh5 = server.h
  316. X
  317. Xh = $(h1) $(h2) $(h3) $(h4) $(h5)
  318. X
  319. Xc1 = addng.c art.c artio.c artsrch.c backpage.c bits.c cheat.c
  320. Xc2 = final.c head.c help.c init.c intrp.c kfile.c last.c $(NDIRC) ng.c
  321. Xc3 = ngdata.c ngsrch.c ngstuff.c only.c rcln.c rcstuff.c respond.c rn.c
  322. Xc4 = rthreads.c rt-rn.c rt-select.c search.c sw.c term.c threads.c util.c
  323. Xc5 = uudecode.c
  324. X#NNTPc6 = $(NNTPDIR)/common/clientlib.c
  325. X
  326. Xc = $(c1) $(c2) $(c3) $(c4) $(c5) $(c6)
  327. Xmtc = mthreads.c mt-read.c mt-process.c mt-write.c threads.c $(c6)
  328. X
  329. Xobj1 = addng.o art.o artio.o artsrch.o backpage.o bits.o cheat.o
  330. Xobj2 = final.o head.o help.o init.o intrp.o kfile.o last.o $(NDIRO) ng.o
  331. Xobj3 = ngdata.o ngsrch.o ngstuff.o only.o rcln.o rcstuff.o respond.o rn.o
  332. Xobj4 = rthreads.o rt-rn.o rt-select.o search.o sw.o term.o threads.o util.o
  333. Xobj5 = uudecode.o
  334. X#NNTPobj6 =  $(NNTPDIR)/common/clientlib.o
  335. X
  336. Xobj = $(obj1) $(obj2) $(obj3) $(obj4) $(obj5) $(obj6)
  337. Xmtobj = mthreads.o mt-read.o mt-process.o mt-write.o threads.o getdate.o $(obj6)
  338. X
  339. Xlintflags = -phbvxac
  340. X
  341. Xadd1 = Makefile.old Pnews Rnmail
  342. Xadd2 = bsd config.h config.sh eunice filexp
  343. Xadd3 = loc makedepend makedir mbox.saver newsetup
  344. Xadd4 = newsgroups newsnews norm.saver
  345. Xadd5 = pdp11 usg v7 ultrix sun hp-ux sgi xenix server.h
  346. Xadd6 = all pyr grimble .falseactive Pnews.header s5uniq
  347. X
  348. Xaddedbyconf = $(add1) $(add2) $(add3) $(add4) $(add5) $(add6)
  349. X
  350. X# grrr
  351. XSHELL = /bin/sh
  352. X
  353. X.c.o:
  354. X    $(CC) -c $(CFLAGS) $*.c
  355. X
  356. Xall: $(public) $(private) $(util)
  357. X    touch all
  358. X
  359. Xtrn: $(obj)
  360. X    $(CC) $(LDFLAGS) $(obj) $(libs) -o trn
  361. X
  362. Xmthreads: $(mtobj)
  363. X    $(CC) $(LDFLAGS) $(mtobj) $(mlibs) -o mthreads
  364. X
  365. X#NNTPgetactive: getactive.o $(NNTPDIR)/common/clientlib.o
  366. X#NNTP    $(CC) $(LDFLAGS) getactive.o $(NNTPDIR)/common/clientlib.o -o getactive $(libs)
  367. X
  368. X# Eek! This is gross.
  369. X$(NNTPDIR)/common/clientlib.o:
  370. X    $(CC) -c $(CFLAGS) $(NNTPINC) $(NNTPDIR)/common/clientlib.c
  371. X    mv clientlib.o $(NNTPDIR)/common/clientlib.o
  372. X
  373. X# if a .h file depends on another .h file...
  374. X$(h):
  375. X    touch $@
  376. X
  377. Xinstall: $(public) $(private) $(manpages)
  378. X# won't work with csh
  379. X    export PATH || exit 1
  380. X    - mv $(rnbin)/trn $(rnbin)/trn.old
  381. X#NNTP    - ln -s trn $(rnbin)/trrn
  382. X    - if test `pwd` != $(rnbin); then cp $(public) $(rnbin); fi
  383. X    cd $(rnbin); chmod 755 $(public); strip trn
  384. X    chmod 755 makedir
  385. X    - ./makedir `./filexp $(rnlib)`
  386. X    - mv $(rnlib)/mthreads $(rnlib)/mthreads.old
  387. X    - if test `pwd` != `./filexp $(rnlib)`; then cp INIT $(private) `./filexp $(rnlib)`; fi
  388. X    - if test ! -f `./filexp $(rnlib)/newsnews`; then cp newsnews `./filexp $(rnlib)`; fi
  389. X    cd `./filexp $(rnlib)`; chmod 755 $(private); chmod 644 INIT newsnews; strip mthreads
  390. X    - if test `pwd` != $(mansrc); then \
  391. Xfor page in $(manpages); do \
  392. Xcp $$page $(mansrc)/`basename $$page .1`.$(manext); \
  393. Xdone; \
  394. X#NNTPecho ".so man$(manext)/trn.$(manext)" > $(mansrc)/trrn.$(manext) ; \
  395. Xfi
  396. X
  397. Xclean:
  398. X    rm -f *.o
  399. X
  400. Xrealclean:
  401. X    rm -f trn mthreads *.o core $(addedbyconf) 
  402. X#NNTP    rm -f $(NNTPDIR)/common/clientlib.o getactive
  403. X
  404. X# The following lint has practically everything turned on.  Unfortunately,
  405. X# you have to wade through a lot of mumbo jumbo that can't be suppressed.
  406. X# If the source file has a /*NOSTRICT*/ somewhere, ignore the lint message
  407. X# for that spot.
  408. X
  409. Xlint: lint_trn lint_mt
  410. X
  411. Xlint_trn:
  412. X    lint $(lintflags) $(defs) $(c) > trn.fuzz
  413. X
  414. Xlint_mt:
  415. X    lint $(lintflags) $(mtc) > mt.fuzz
  416. X
  417. Xdepend:
  418. X    ./makedepend
  419. X
  420. X# AUTOMATICALLY GENERATED MAKE DEPENDENCIES--PUT NOTHING BELOW THIS LINE
  421. X$(obj):
  422. X    @ echo "You haven't done a "'"make depend" yet!'; exit 1
  423. X!NO!SUBS!
  424. Xcase "$isrrn" in
  425. Xdefine)  sed < Makefile -e '/^#NNTP/s/^#NNTP//' > Makefile.new ;;
  426. X*) sed < Makefile -e '/^#NNTP/d' > Makefile.new ;;
  427. Xesac
  428. Xmv Makefile.new Makefile
  429. X$eunicefix Makefile
  430. END_OF_FILE
  431.   if test 6240 -ne `wc -c <'Makefile.SH'`; then
  432.     echo shar: \"'Makefile.SH'\" unpacked with wrong size!
  433.   fi
  434.   chmod +x 'Makefile.SH'
  435.   # end of 'Makefile.SH'
  436. fi
  437. if test -f 'Rnmail.SH' -a "${1}" != "-c" ; then 
  438.   echo shar: Will not clobber existing file \"'Rnmail.SH'\"
  439. else
  440.   echo shar: Extracting \"'Rnmail.SH'\" \(6853 characters\)
  441.   sed "s/^X//" >'Rnmail.SH' <<'END_OF_FILE'
  442. Xcase $CONFIG in
  443. X    '') . ./config.sh ;;
  444. Xesac
  445. Xecho "Extracting Rnmail (with variable substitutions)"
  446. X$spitshell >Rnmail <<!GROK!THIS!
  447. X$startsh
  448. X# $Header: Rnmail.SH,v 4.3.3.3 91/01/16 03:28:46 davison Trn $
  449. X# 
  450. X# $Log:    Rnmail.SH,v $
  451. X# Revision 4.3.3.3  91/01/16  03:28:46  davison
  452. X# Integrated rn patches 48-54.
  453. X# 
  454. X# Revision 4.3.3.2  90/08/20  16:22:29  davison
  455. X# Use mbox.saver for MAILRECORD.  Fixed sitename handling.
  456. X# 
  457. X# Revision 4.3.3.1  90/07/24  22:02:49  davison
  458. X# Initial Trn Release
  459. X# 
  460. X# Revision 4.3.2.3  90/12/30  03:48:04  sob
  461. X# Changed "hidden" to "hiddennet" to be like nntp and bnews.
  462. X# Made it possible to cancel articles if hiddennet is defined.
  463. X# 
  464. X# Revision 4.3.2.2  90/11/22  14:00:21  sob
  465. X# Support added for hiding all hosts within a domain such that mail appears
  466. X# to come for user@domainname only.
  467. X# 
  468. X# Revision 4.3.2.1  89/11/06  00:30:54  sob
  469. X# Added RRN support from NNTP 1.5
  470. X# 
  471. X# Revision 4.3.1.4  85/08/01  14:23:05  lwall
  472. X# Added MAILRECORD.  Temp file is no longer in /tmp.  'e editor' added.
  473. X# 
  474. X# Revision 4.3.1.3  85/05/20  16:25:17  lwall
  475. X# Shouldn't ask editor if EDITOR or VISUAL defined.
  476. X# 
  477. X# Revision 4.3.1.2  85/05/17  10:36:19  lwall
  478. X# Added "-- " before .signature.
  479. X# 
  480. X# Revision 4.3.1.1  85/05/10  11:30:38  lwall
  481. X# Branch for patches.
  482. X# 
  483. X# Revision 4.3  85/05/01  11:34:18  lwall
  484. X# Baseline for release with 4.3bsd.
  485. X# 
  486. X#
  487. X# syntax: Rnmail -h headerfile [oldart]        or
  488. X#         Rnmail destination-list         or just
  489. X#         Rnmail
  490. X
  491. Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
  492. X
  493. X# System dependencies
  494. X
  495. Xmailer="${mailer-/bin/mail}"
  496. X# if you change this to something that does signatures, take out signature code
  497. X
  498. X# your site name
  499. Xcase $portable in
  500. Xdefine)
  501. X    case "$hostcmd" in
  502. X    '') sitename="$sitename" ;;
  503. X    *)  sitename=\`$hostcmd\` ;;
  504. X    esac
  505. X    case \$sitename in
  506. X        *.*)
  507. X            ;;
  508. X        *)
  509. X            sitename=\${sitename}.$domain
  510. X            ;;
  511. X    esac
  512. X    ;;
  513. Xundef) sitename="$sitename" ;;
  514. Xesac
  515. X
  516. Xcase $hiddennet in
  517. Xdefine)    sitename="$domain"
  518. X    ;;
  519. X*)
  520. X    ;;
  521. Xesac
  522. X
  523. X# your organization name
  524. Xorgname="$orgname"
  525. X# what pager you use--if you have kernal paging use cat
  526. Xpager="\${PAGER-$pager}"
  527. X# how you derive full names, bsd, usg, or other
  528. Xnametype="$nametype"
  529. X# default editor
  530. Xdefeditor="$defeditor"
  531. X# where the non-publics are
  532. Xrnlib=$rnlib
  533. X# how not to do a newline with echo
  534. Xn="$n"
  535. Xc="$c"
  536. X
  537. Xtest=${test-test}
  538. Xsed=${sed-sed}
  539. Xecho=${echo-echo}
  540. Xcat=${cat-cat}
  541. Xgrep=${grep-grep}
  542. Xrm=${rm-rm}
  543. X
  544. X!GROK!THIS!
  545. X$spitshell >>Rnmail <<'!NO!SUBS!'
  546. Xdotdir=${DOTDIR-${HOME-$LOGDIR}}
  547. Xtmpart=$dotdir/.letter
  548. X
  549. Xheaderfile=""
  550. Xcase $# in
  551. X0) ;;
  552. X*)  case $1 in
  553. X    -h)
  554. X    headerfile="$2"
  555. X    case $# in
  556. X    3) oldart=$3 ;;
  557. X    esac
  558. X    ;;
  559. X    esac
  560. X    ;;
  561. Xesac
  562. X
  563. Xcase $headerfile in
  564. X'')
  565. X    case $# in
  566. X    0)
  567. X    to=h
  568. X    while $test "$to" = h ; do
  569. X        $echo ""
  570. X        $echo $n "To: $c"
  571. X        read to
  572. X        case $to in
  573. X        h)
  574. X        $cat <<'EOH'
  575. X
  576. XType the net address of those people that you wish the message sent to.
  577. XAdditional recipients may be added on the Cc: line when you edit.
  578. X
  579. XSeparate multiple addresses with spaces.
  580. X
  581. XEOH
  582. X        ;;
  583. X        esac
  584. X    done
  585. X    ;;
  586. X    *)
  587. X    to="$*"
  588. X    ;;
  589. X    esac
  590. X    to=`$echo "$to" | $sed 's/  */ /g'`
  591. X
  592. X    title=h
  593. X    while $test "$title" = h ; do
  594. X    $echo ""
  595. X    $echo $n "Title/Subject: $c"
  596. X    read title
  597. X    case $title in
  598. X    h)
  599. X        $cat <<'EOH'
  600. X
  601. XType the title for your message.  
  602. XEOH
  603. X        ;;
  604. X    esac
  605. X    done
  606. X
  607. X# now build a file with a header for them to edit
  608. X    
  609. X    orgname=${ORGANIZATION-$orgname}
  610. X    case $orgname in
  611. X    /*) orgname=`$cat $orgname` ;;
  612. X    esac
  613. X
  614. X    $sed -e '/^Reply-To: $/d' > $tmpart <<EOHeader
  615. XTo: $to
  616. XSubject: $title
  617. XOrganization: $orgname
  618. XReply-To: $REPLYTO
  619. XCc:
  620. XBcc:
  621. X
  622. XEOHeader
  623. X
  624. X    ;;
  625. X*)
  626. X    $cat < $headerfile  > $tmpart
  627. X    ;;
  628. Xesac
  629. X
  630. X
  631. Xfile=h
  632. Xwhile $test "$file" = h ; do
  633. X    $echo ""
  634. X    $echo $n "Prepared file to include [none]: $c"
  635. X    read file
  636. X    case $file in
  637. X    h)
  638. X    $cat <<'EOH'
  639. X
  640. XIf you have already produced the body of your message, type the filename
  641. Xfor it here.  If you just want to proceed directly to the editor, type a
  642. XRETURN.  In any event, you will be allowed to edit as many times as you
  643. Xwant before you send off the message.
  644. XEOH
  645. X    ;;
  646. X    '')
  647. X    $echo "" >> $tmpart
  648. X    state=edit
  649. X    ;;
  650. X    *)
  651. X    $cat $file >>$tmpart
  652. X    state=ask
  653. X    ;;
  654. X    esac
  655. Xdone
  656. X
  657. X$echo ""
  658. X
  659. Xwhile true ; do
  660. X    case $state in
  661. X    edit)
  662. X    rescue="sleep 1; $cat $tmpart >>${HOME-$LOGDIR}/dead.letter ; $echo Message appended to ${HOME-$LOGDIR}/dead.letter ; exit"
  663. X    trap "$rescue" 1
  664. X    trap : 2
  665. X    case "${VISUAL-${EDITOR-}}" in
  666. X    '')
  667. X        tmp=h
  668. X        ;;
  669. X    *)
  670. X        tmp=''
  671. X        ;;
  672. X    esac
  673. X    while $test "$tmp" = h ; do
  674. X        $echo $n "Editor [${VISUAL-${EDITOR-$defeditor}}]: $c"
  675. X        read tmp
  676. X        case $tmp in
  677. X        h)
  678. X        $cat <<'EOH'
  679. X
  680. XType a return to get the default editor, or type the name of the editor you
  681. Xprefer.  The default editor depends on the VISUAL and EDITOR environment
  682. Xvariables.
  683. X
  684. XEOH
  685. X        ;;
  686. X        '')
  687. X        ;;
  688. X        *)
  689. X        VISUAL=$tmp
  690. X        export VISUAL
  691. X        ;;
  692. X        esac
  693. X    done
  694. X    ${VISUAL-${EDITOR-$defeditor}} $tmpart $oldart
  695. X    trap "$rescue" 2
  696. X    state=ask
  697. X    ;;
  698. X    
  699. X    ask)
  700. X    $echo ""
  701. X    $echo $n "Send, abort, edit, or list? $c"
  702. X    read ans
  703. X    
  704. X    case $ans in
  705. X    a*)
  706. X        state=rescue
  707. X        ;;
  708. X    e*)
  709. X        set $ans
  710. X        case $# in
  711. X        2)  VISUAL="$2" ;;
  712. X        esac
  713. X        state=edit
  714. X        ;;
  715. X    l*)
  716. X        $pager $tmpart
  717. X        state=ask
  718. X        ;;
  719. X    s*)
  720. X        state=send
  721. X        ;;
  722. X    h*)
  723. X        $cat <<'EOH'
  724. X
  725. XType s to send the message, a to abort and append the message to dead.letter,
  726. Xe to edit the message again, or l to list the message.
  727. X
  728. XTo invoke an alternate editor, type 'e editor'.
  729. XEOH
  730. X    esac
  731. X    ;;
  732. X    
  733. X    send)
  734. X    if $test -f $dotdir/.signature; then
  735. X        $echo $n "Append .signature file? [y] $c"
  736. X        read ans
  737. X        case $ans in
  738. X        ''|y*)
  739. X        $echo "-- " >> $tmpart
  740. X        cat $dotdir/.signature >> $tmpart
  741. X        ;;
  742. X        esac
  743. X    fi
  744. X    case $mailer in
  745. X    *sendmail)
  746. X        $mailer -t <$tmpart
  747. X        ;;
  748. X# but recmail does not know about Bcc, alas
  749. X    *recmail)
  750. X        $mailer <$tmpart
  751. X        ;;
  752. X    *)
  753. X        set X `$sed <$tmpart -n -e '/^To:/{' -e 's/To: *//p' -e q -e '}'`
  754. X        shift
  755. X        set X "$@" `$sed <$tmpart -n -e '/^Cc:/{' -e 's/Cc: *//p' -e q -e '}'`
  756. X        shift
  757. X        set X "$@" `$sed <$tmpart -n -e '/^Bcc:/{' -e 's/Bcc: *//p' -e q -e '}'`
  758. X        shift
  759. X        $grep -v "^Bcc:"  <$tmpart | $mailer "$@"
  760. X        ;;
  761. X    esac
  762. X    case $? in
  763. X    0)
  764. X        state=cleanup
  765. X        ;;
  766. X    *)
  767. X        state=rescue
  768. X        ;;
  769. X    esac
  770. X    ;;
  771. X    rescue)
  772. X    $cat $tmpart >> ${HOME-$LOGDIR}/dead.letter
  773. X    $echo "Message appended to ${HOME-$LOGDIR}/dead.letter"
  774. X    $echo "A copy may be temporarily found in $tmpart"
  775. X    exit
  776. X    ;;
  777. X    cleanup)
  778. X    case "${MAILRECORD-none}" in
  779. X    none)
  780. X        ;;
  781. X    *)
  782. X        set X ${USER-${LOGNAME-`who am i`}} unknown
  783. X        shift
  784. X        $rnlib/mbox.saver $tmpart "." "." 0 0 Pnews $MAILRECORD "From $1 `date`"
  785. X        if $test $? -eq 0 ; then
  786. X        $echo "Message appended to $MAILRECORD"
  787. X        else
  788. X        $echo "Cannot append to $MAILRECORD"
  789. X        fi
  790. X        ;;
  791. X    esac
  792. X    exit
  793. X    ;;
  794. X    esac
  795. Xdone
  796. X!NO!SUBS!
  797. X$eunicefix Rnmail
  798. Xchmod 755 Rnmail
  799. END_OF_FILE
  800.   if test 6853 -ne `wc -c <'Rnmail.SH'`; then
  801.     echo shar: \"'Rnmail.SH'\" unpacked with wrong size!
  802.   fi
  803.   chmod +x 'Rnmail.SH'
  804.   # end of 'Rnmail.SH'
  805. fi
  806. if test -f 'artsrch.c' -a "${1}" != "-c" ; then 
  807.   echo shar: Will not clobber existing file \"'artsrch.c'\"
  808. else
  809.   echo shar: Extracting \"'artsrch.c'\" \(8042 characters\)
  810.   sed "s/^X//" >'artsrch.c' <<'END_OF_FILE'
  811. X/* $Header: artsrch.c,v 4.3.3.1 90/07/21 20:13:13 davison Trn $
  812. X *
  813. X * $Log:    artsrch.c,v $
  814. X * Revision 4.3.3.1  90/07/21  20:13:13  davison
  815. X * Initial Trn Release
  816. X * 
  817. X * Revision 4.3.2.4  89/11/27  01:30:00  sob
  818. X * Altered NNTP code per ideas suggested by Bela Lubkin
  819. X * <filbo@gorn.santa-cruz.ca.us>
  820. X * 
  821. X * Revision 4.3.2.3  89/11/26  22:54:37  sob
  822. X * Added new patches to make rrn faster.
  823. X * 
  824. X * Revision 4.3.2.2  89/11/26  22:20:57  sob
  825. X * Added better NNTP support.
  826. X * 
  827. X * Revision 4.3.2.1  89/11/26  22:13:10  sob
  828. X * Added support for NNTP
  829. X * 
  830. X * Revision 4.3  85/05/01  11:35:47  lwall
  831. X * Baseline for release with 4.3bsd.
  832. X * 
  833. X */
  834. X
  835. X#include "EXTERN.h"
  836. X#include "common.h"
  837. X#include "search.h"
  838. X#include "term.h"
  839. X#include "util.h"
  840. X#include "intrp.h"
  841. X#include "bits.h"
  842. X#include "kfile.h"
  843. X#include "head.h"
  844. X#include "final.h"
  845. X#include "cheat.h"
  846. X#ifdef SERVER
  847. X#include "server.h"
  848. X#endif
  849. X#include "ng.h"
  850. X#include "artio.h"
  851. X#ifdef USETHREADS
  852. X#include "rthreads.h"
  853. X#include "ngdata.h"
  854. X#endif
  855. X#include "INTERN.h"
  856. X#include "artsrch.h"
  857. X
  858. Xvoid
  859. Xartsrch_init()
  860. X{
  861. X#ifdef ARTSEARCH
  862. X#ifdef ZEROGLOB
  863. X    init_compex(&sub_compex);
  864. X    init_compex(&art_compex);
  865. X#endif
  866. X#endif
  867. X}
  868. X
  869. X/* search for an article containing some pattern */
  870. X
  871. X#ifdef ARTSEARCH
  872. Xint
  873. Xart_search(patbuf,patbufsiz,get_cmd)
  874. Xchar *patbuf;                /* if patbuf != buf, get_cmd must */
  875. Xint patbufsiz;
  876. Xint get_cmd;                /*   be set to FALSE!!! */
  877. X{
  878. X    char *pattern;            /* unparsed pattern */
  879. X    register char cmdchr = *patbuf;    /* what kind of search? */
  880. X    register char *s;
  881. X    bool backward = cmdchr == '?' || cmdchr == Ctl('p');
  882. X                    /* direction of search */
  883. X    COMPEX *compex;            /* which compiled expression */
  884. X    char *cmdlst = Nullch;        /* list of commands to do */
  885. X    int normal_return = SRCH_NOTFOUND;    /* assume no commands */
  886. X    bool saltaway = FALSE;        /* store in KILL file? */
  887. X    char howmuch;            /* search just the subjects */
  888. X    bool doread;            /* search read articles? */
  889. X    bool foldcase = TRUE;        /* fold upper and lower case? */
  890. X
  891. X    int_count = 0;
  892. X    if (cmdchr == '/' || cmdchr == '?') {    /* normal search? */
  893. X    if (get_cmd && buf == patbuf)
  894. X        if (!finish_command(FALSE))    /* get rest of command */
  895. X        return SRCH_ABORT;
  896. X    compex = &art_compex;
  897. X    if (patbuf[1]) {
  898. X        howmuch = 0;
  899. X        doread = FALSE;
  900. X    }
  901. X    else {
  902. X        howmuch = art_howmuch;
  903. X        doread = art_doread;
  904. X    }
  905. X    s = cpytill(buf,patbuf+1,cmdchr);/* ok to cpy buf+1 to buf */
  906. X    pattern = buf;
  907. X    if (*pattern) {
  908. X        if (*lastpat)
  909. X        free(lastpat);
  910. X        lastpat = savestr(pattern);
  911. X    }
  912. X    if (*s) {            /* modifiers or commands? */
  913. X        for (s++; *s && index("Kharc",*s); s++) {
  914. X        if (*s == 'h')        /* scan header */
  915. X            howmuch = 1;
  916. X        else if (*s == 'a')    /* scan article */
  917. X            howmuch = 2;
  918. X        else if (*s == 'r')    /* scan read articles */
  919. X            doread = TRUE;
  920. X        else if (*s == 'K')    /* put into KILL file */
  921. X            saltaway = TRUE;
  922. X        else if (*s == 'c')    /* make search case sensitive */
  923. X            foldcase = FALSE;
  924. X        }
  925. X    }
  926. X    while (isspace(*s) || *s == ':')
  927. X        s++;
  928. X    if (*s) {
  929. X        if (*s == 'm' || *s == 'M')
  930. X        doread = TRUE;
  931. X        if (*s == 'k')        /* grandfather clause */
  932. X        *s = 'j';
  933. X        cmdlst = savestr(s);
  934. X        normal_return = SRCH_DONE;
  935. X    }
  936. X    art_howmuch = howmuch;
  937. X    art_doread = doread;
  938. X    if (srchahead)
  939. X        srchahead = -1;
  940. X    }
  941. X    else {
  942. X    register char *h;
  943. X
  944. X    howmuch = 0;            /* just search subjects */
  945. X    doread = (cmdchr == Ctl('p'));
  946. X    if (cmdchr == Ctl('n'))
  947. X        normal_return = SRCH_SUBJDONE;
  948. X    compex = &sub_compex;
  949. X    pattern = patbuf+1;
  950. X    strcpy(pattern,": *");
  951. X    h = pattern + strlen(pattern);
  952. X    interp(h,patbufsiz - (h-patbuf),"%s");    /* fetch current subject */
  953. X    if (cmdchr == 'K') {
  954. X        saltaway = TRUE;
  955. X        cmdchr = 'k';
  956. X    }
  957. X    if (cmdchr == 'k') {
  958. X        normal_return = SRCH_DONE;
  959. X        cmdlst = savestr("j");
  960. X        mark_as_read();        /* this article has this subject */
  961. X        if (!*h) {
  962. X#ifdef VERBOSE
  963. X        IF(verbose)
  964. X            fputs("\nCannot delete null subject.\n",stdout) FLUSH;
  965. X        ELSE
  966. X#endif
  967. X#ifdef TERSE
  968. X            fputs("\nNull subject.\n",stdout) FLUSH;
  969. X#endif
  970. X        return SRCH_ABORT;
  971. X        }
  972. X#ifdef VERBOSE
  973. X        else if (verbose)
  974. X        printf("\nMarking subject \"%s\" as read.\n",h) FLUSH;
  975. X#endif
  976. X    }
  977. X    else if (!srchahead)
  978. X        srchahead = -1;
  979. X    h[24] = '\0';        /* compensate for notesfiles */
  980. X    while (*h) {
  981. X        if (index("/\\[.^*$'\"",*h) != Nullch)
  982. X        *h++ = '.';
  983. X        else
  984. X        h++;
  985. X    }
  986. X#ifdef DEBUGGING
  987. X    if (debug) {
  988. X        printf("\npattern = %s\n",pattern) FLUSH;
  989. X    }
  990. X#endif
  991. X    }
  992. X    if ((s = compile(compex,pattern,TRUE,foldcase)) != Nullch) {
  993. X                    /* compile regular expression */
  994. X    printf("\n%s\n",s) FLUSH;
  995. X    return SRCH_ABORT;
  996. X    }
  997. X#ifdef KILLFILES
  998. X    if (saltaway) {
  999. X    char saltbuf[LBUFLEN];
  1000. X
  1001. X    s = saltbuf;
  1002. X    sprintf(s,"/%s/",pattern);
  1003. X    s += strlen(s);
  1004. X    if (doread)
  1005. X        *s++ = 'r';
  1006. X    if (howmuch==1)
  1007. X        *s++ = 'h';
  1008. X    else if (howmuch==2)
  1009. X        *s++ = 'a';
  1010. X    *s++ = ':';
  1011. X    if (!cmdlst)
  1012. X        cmdlst = savestr("j");
  1013. X    safecpy(s,cmdlst,LBUFLEN-(s-saltbuf));
  1014. X    kf_append(saltbuf);
  1015. X    }
  1016. X#endif
  1017. X    if (cmdlst && index(cmdlst,'='))
  1018. X    normal_return = SRCH_ERROR;    /* listing subjects is an error? */
  1019. X    if (get_cmd) {
  1020. X    fputs("\nSearching...\n",stdout) FLUSH;
  1021. X                    /* give them something to read */
  1022. X    }
  1023. X#ifdef USETHREADS
  1024. X    if (mode == 't') {
  1025. X    if (!cmdlst)
  1026. X        cmdlst = savestr("+");    /* thread selector's default command */
  1027. X    if (unread_selector)
  1028. X        doread = TRUE;
  1029. X    normal_return = SRCH_DONE;
  1030. X    }
  1031. X#endif
  1032. X    if (backward) {
  1033. X    if (cmdlst && art <= lastart)
  1034. X        art++;            /* include current article */
  1035. X    if (doread)
  1036. X        check_first(absfirst);
  1037. X    }
  1038. X    else {
  1039. X    if (art > lastart) {
  1040. X        art = (doread ? absfirst : firstart);
  1041. X        check_first(art--);
  1042. X    }
  1043. X    else if (cmdlst && art >= absfirst)
  1044. X        art--;            /* include current article */
  1045. X    }
  1046. X    if (srchahead > 0) {
  1047. X    if (!backward)
  1048. X        art = srchahead - 1;
  1049. X    srchahead = -1;
  1050. X    }
  1051. X    assert(!cmdlst || *cmdlst);
  1052. X    perform_cnt = 0;
  1053. X    for (;;) {
  1054. X    if (backward ?
  1055. X        (--art < absfirst || (!doread && art < firstart)) :
  1056. X        (++art > lastart)
  1057. X      ) {            /* out of articles? */
  1058. X        if (cmdlst)
  1059. X        free(cmdlst);
  1060. X        return normal_return;
  1061. X    }
  1062. X    if (int_count) {
  1063. X        int_count = 0;
  1064. X        if (cmdlst)
  1065. X        free(cmdlst);
  1066. X        return SRCH_INTR;
  1067. X    }
  1068. X    /*NOSTRICT*/
  1069. X    if (doread || !was_read(art)) {
  1070. X        if (wanted(compex,art,howmuch)) {
  1071. X                    /* does the shoe fit? */
  1072. X        if (cmdlst) {
  1073. X            if (perform(cmdlst,TRUE)) {
  1074. X            if (cmdlst)
  1075. X                free(cmdlst);
  1076. X            return SRCH_INTR;
  1077. X            }
  1078. X        }
  1079. X        else {
  1080. X            if (cmdlst)
  1081. X            free(cmdlst);
  1082. X            return SRCH_FOUND;
  1083. X        }
  1084. X        }
  1085. X        else if (!cmdlst && ! (art%50)) {
  1086. X        printf("...%ld",(long)art);
  1087. X        fflush(stdout);
  1088. X        }
  1089. X    }
  1090. X    }
  1091. X}
  1092. X
  1093. X/* determine if article fits pattern */
  1094. X/* returns TRUE if it exists and fits pattern, FALSE otherwise */
  1095. X
  1096. Xbool
  1097. Xwanted(compex, artnum, scope)
  1098. XCOMPEX *compex;
  1099. XART_NUM artnum;
  1100. Xchar scope;
  1101. X{
  1102. X    if (!scope) {
  1103. X    char subj_buf[266];
  1104. X    
  1105. X#ifdef USETHREADS
  1106. X    if (ThreadedGroup)
  1107. X        find_article(art);
  1108. X    if (p_art) {
  1109. X        if (mode != 't')
  1110. X        strcpy(subj_buf, "Subject: ");
  1111. X        else
  1112. X        *subj_buf = '\0';
  1113. X        if (p_art->subject != -1)
  1114. X        strcat(subj_buf,subject_ptrs[p_art->subject]);
  1115. X    }
  1116. X    else
  1117. X#endif
  1118. X    {
  1119. X        strcpy(subj_buf, "Subject: ");
  1120. X        strncpy(subj_buf+9,fetchsubj(artnum,FALSE,FALSE),256);
  1121. X    }
  1122. X#ifdef DEBUGGING
  1123. X    if (debug & DEB_SEARCH_AHEAD)
  1124. X        printf("%s\n",subj_buf) FLUSH;
  1125. X#endif
  1126. X    return execute(compex,subj_buf) != Nullch;
  1127. X    }
  1128. X#ifdef CACHESUBJ
  1129. X    else
  1130. X    fetchsubj(artnum,FALSE,FALSE);/* might as well get subject handy */
  1131. X#endif
  1132. X    
  1133. X#ifdef SERVER
  1134. X    if (scope == 1){
  1135. X    if (nntpopen(artnum,GET_HEADER) == Nullfp) /* we only need the header */
  1136. X        return FALSE;
  1137. X    }
  1138. X    else
  1139. X#endif
  1140. X    if (artopen(artnum) == Nullfp)    /* ensure that article is open */
  1141. X
  1142. X    return FALSE;            /* if not, return NO MATCH */
  1143. X    scope--;
  1144. X    while (fgets(buf,LBUFLEN,artfp) != Nullch) {
  1145. X                    /* for each line of article */
  1146. X    if (!scope && index(buf,':') == Nullch && *buf != ' ' && *buf != '\t')
  1147. X                    /* if headers only and out of header */
  1148. X        return FALSE;        /* say no go */
  1149. X    if (execute(compex,buf) != Nullch) {
  1150. X                    /* does pattern matcher match? */
  1151. X        return TRUE;        /* say Eureka */
  1152. X    }
  1153. X    }
  1154. X    return FALSE;            /* out of article, so no match */
  1155. X}
  1156. X#endif
  1157. X
  1158. END_OF_FILE
  1159.   if test 8042 -ne `wc -c <'artsrch.c'`; then
  1160.     echo shar: \"'artsrch.c'\" unpacked with wrong size!
  1161.   fi
  1162.   # end of 'artsrch.c'
  1163. fi
  1164. if test -f 'final.c' -a "${1}" != "-c" ; then 
  1165.   echo shar: Will not clobber existing file \"'final.c'\"
  1166. else
  1167.   echo shar: Extracting \"'final.c'\" \(5537 characters\)
  1168.   sed "s/^X//" >'final.c' <<'END_OF_FILE'
  1169. X/* $Header: final.c,v 4.3.3.2 91/01/16 02:38:15 davison Trn $
  1170. X *
  1171. X * $Log:    final.c,v $
  1172. X * Revision 4.3.3.2  91/01/16  02:38:15  davison
  1173. X * Integrated rn patches 48-54.
  1174. X * 
  1175. X * Revision 4.3.3.1  90/06/20  22:36:57  davison
  1176. X * Initial Trn Release
  1177. X * 
  1178. X * Revision 4.3.2.9  90/11/22  16:08:34  sob
  1179. X * Added changes to accomodate pick C preprocessors.
  1180. X * 
  1181. X * Revision 4.3.2.8  90/04/14  19:37:14  sob
  1182. X * Added better support for the NeXT.
  1183. X * 
  1184. X * Revision 4.3.2.7  90/03/17  21:33:49  sob
  1185. X * cleaned up a bit
  1186. X * 
  1187. X * Revision 4.3.2.6  90/03/17  16:48:25  sob
  1188. X * Added changes to insure that rrn cleans up its temporary files when
  1189. X * exiting.
  1190. X * 
  1191. X * Revision 4.3.2.5  89/11/28  01:51:28  sob
  1192. X * Now handles SIGWINCH correctly.
  1193. X * 
  1194. X * Revision 4.3.2.4  89/11/27  01:30:24  sob
  1195. X * Altered NNTP code per ideas suggested by Bela Lubkin
  1196. X * <filbo@gorn.santa-cruz.ca.us>
  1197. X * 
  1198. X * Revision 4.3.2.3  89/11/08  02:25:07  sob
  1199. X * Integrated modifications from other RRN patches colleceted from USENET
  1200. X * 
  1201. X * Revision 4.3.2.2  89/11/07  23:26:31  sob
  1202. X * Added some fixes that relate to SIGSTP
  1203. X * 
  1204. X * Revision 4.3.2.1  89/11/06  00:16:08  sob
  1205. X * Added RRN support from NNTP 1.5
  1206. X *
  1207. X * Revision 4.3  85/05/01  11:38:08  lwall
  1208. X * Baseline for release with 4.3bsd.
  1209. X * 
  1210. X */
  1211. X
  1212. X#include "EXTERN.h"
  1213. X#include "common.h"
  1214. X#include "util.h"
  1215. X#include "term.h"
  1216. X#include "ng.h"
  1217. X#include "init.h"
  1218. X#include "bits.h"
  1219. X#include "last.h"
  1220. X#include "rcstuff.h"
  1221. X#include "ngdata.h"
  1222. X#include "artio.h"
  1223. X#include "INTERN.h"
  1224. X#include "final.h"
  1225. X
  1226. Xvoid
  1227. Xfinal_init()
  1228. X{
  1229. X#ifdef SIGTSTP
  1230. X    sigset(SIGTSTP, stop_catcher);    /* job control signals */
  1231. X    sigset(SIGTTOU, stop_catcher);    /* job control signals */
  1232. X    sigset(SIGTTIN, stop_catcher);    /* job control signals */
  1233. X#endif
  1234. X
  1235. X    sigset(SIGINT, int_catcher);    /* always catch interrupts */
  1236. X#ifdef SIGHUP
  1237. X    sigset(SIGHUP, sig_catcher);    /* and hangups */
  1238. X#endif
  1239. X#ifndef lint
  1240. X#ifdef SIGEMT
  1241. X    sigignore(SIGEMT);
  1242. X#endif
  1243. X#endif /* lint */
  1244. X
  1245. X    sigset(SIGILL, sig_catcher);
  1246. X#ifdef SIGTRAP
  1247. X    sigset(SIGTRAP, sig_catcher);
  1248. X#endif
  1249. X    sigset(SIGFPE, sig_catcher);
  1250. X#ifdef SIGBUS
  1251. X    sigset(SIGBUS, sig_catcher);
  1252. X#endif
  1253. X    sigset(SIGSEGV, sig_catcher);
  1254. X#ifdef SIGSYS
  1255. X    sigset(SIGSYS, sig_catcher);
  1256. X#endif
  1257. X    sigset(SIGTERM, sig_catcher);
  1258. X#ifdef SIGXCPU
  1259. X    sigset(SIGXCPU, sig_catcher);
  1260. X#endif
  1261. X#ifdef SIGXFSZ
  1262. X    sigset(SIGXFSZ, sig_catcher);
  1263. X#endif
  1264. X#ifdef SIGWINCH
  1265. X    sigset(SIGWINCH, winch_catcher);
  1266. X#endif
  1267. X}
  1268. X
  1269. Xvoid                    /* very much void */
  1270. Xfinalize(status)
  1271. Xint status;
  1272. X{
  1273. X#ifdef SERVER
  1274. X    char artname[32];
  1275. X#endif /* SERVER */
  1276. X
  1277. X    if (bizarre)
  1278. X    resetty();
  1279. X    if (lockname && *lockname)
  1280. X     UNLINK(lockname);
  1281. X#ifdef SERVER
  1282. X    if (*active_name)
  1283. X    UNLINK(active_name);
  1284. X    if (openart) {
  1285. X     char artname[32];
  1286. X     sprintf(artname, "/tmp/rrn%ld.%d", (long)openart, getpid());
  1287. X     UNLINK(artname);
  1288. X    }
  1289. X    close_server();
  1290. X#endif /* SERVER */
  1291. X    if (status < 0) {
  1292. X    chdir("/usr/tmp");
  1293. X    sigset(SIGILL,SIG_DFL);
  1294. X    abort();
  1295. X    }
  1296. X    exit(status);
  1297. X}
  1298. X
  1299. X/* come here on interrupt */
  1300. X
  1301. XSIGRET
  1302. Xint_catcher()
  1303. X{
  1304. X    sigset(SIGINT,int_catcher);
  1305. X#ifdef DEBUGGING
  1306. X    if (debug)
  1307. X    write(2,"int_catcher\n",12);
  1308. X#endif
  1309. X    if (!waiting) {
  1310. X    if (int_count) {        /* was there already an interrupt? */
  1311. X        write(2,"\nBye-bye.\n",10);
  1312. X        sig_catcher(0);        /* emulate the other signals */
  1313. X    }
  1314. X    int_count++;
  1315. X    }
  1316. X}
  1317. X
  1318. X/* come here on signal other than interrupt, stop, or cont */
  1319. X
  1320. XSIGRET
  1321. Xsig_catcher(signo)
  1322. X{
  1323. X#ifdef VERBOSE
  1324. X    static char *signame[] = {
  1325. X    "",
  1326. X    "HUP",
  1327. X    "INT",
  1328. X    "QUIT",
  1329. X    "ILL",
  1330. X    "TRAP",
  1331. X    "IOT",
  1332. X    "EMT",
  1333. X    "FPE",
  1334. X    "KILL",
  1335. X    "BUS",
  1336. X    "SEGV",
  1337. X    "SYS",
  1338. X    "PIPE",
  1339. X    "ALRM",
  1340. X    "TERM",
  1341. X    "???"
  1342. X#ifdef SIGTSTP
  1343. X    ,"STOP",
  1344. X    "TSTP",
  1345. X    "CONT",
  1346. X    "CHLD",
  1347. X    "TTIN",
  1348. X    "TTOU",
  1349. X    "TINT",
  1350. X    "XCPU",
  1351. X    "XFSZ"
  1352. X#ifdef SIGPROF
  1353. X    ,"VTALARM",
  1354. X    "PROF"
  1355. X#endif
  1356. X#endif
  1357. X    };
  1358. X#endif
  1359. X
  1360. X#ifdef DEBUGGING
  1361. X    if (debug) {
  1362. X    printf("\nSIG%s--.newsrc not restored in debug\n",signame[signo]);
  1363. X    finalize(-1);
  1364. X    }
  1365. X#endif
  1366. X    if (panic)
  1367. X    abort();
  1368. X    (void) sigset(SIGILL,SIG_DFL);
  1369. X    panic = TRUE;            /* disable terminal I/O */
  1370. X    if (doing_ng) {            /* need we reconstitute rc line? */
  1371. X    yankback();
  1372. X    restore_ng();            /* then do so (hope this works) */
  1373. X    }
  1374. X    doing_ng = FALSE;
  1375. X    if (rc_changed)            /* need we write .newsrc out? */
  1376. X    write_rc();            /* then do so */
  1377. X    rc_changed = FALSE;
  1378. X#ifdef SIGHUP
  1379. X    if (signo != SIGHUP)
  1380. X#endif
  1381. X#ifdef VERBOSE
  1382. X    IF(verbose)
  1383. X        printf("\nCaught %s%s--.newsrc restored\n",
  1384. X        signo ? "a SIG" : "an internal error", signame[signo]);
  1385. X    ELSE
  1386. X#endif
  1387. X#ifdef TERSE
  1388. X        printf("\nSignal %d--bye bye\n",signo);
  1389. X#endif
  1390. X    switch (signo) {
  1391. X#ifdef SIGBUS
  1392. X    case SIGBUS:
  1393. X#endif
  1394. X    case SIGILL:
  1395. X    case SIGSEGV:
  1396. X    finalize(-signo);
  1397. X    }
  1398. X    finalize(1);                /* and blow up */
  1399. X}
  1400. X
  1401. X#ifdef SIGTSTP
  1402. X/* come here on stop signal */
  1403. X
  1404. XSIGRET
  1405. Xstop_catcher(signo)
  1406. Xint signo;
  1407. X{
  1408. X    if (!waiting) {
  1409. X    checkpoint_rc();        /* good chance of crash while stopped */
  1410. X    if (clear_on_stop) {
  1411. X        clear();
  1412. X        putchar('\n') FLUSH;
  1413. X    }
  1414. X    resetty();            /* this is the point of all this */
  1415. X#ifdef DEBUGGING
  1416. X    if (debug)
  1417. X        write(2,"stop_catcher\n",13);
  1418. X#endif
  1419. X    sigset(signo,SIG_DFL);    /* enable stop */
  1420. X#ifdef SIGBLOCK
  1421. X    sigsetmask(sigblock(0) & ~(1 << (signo-1)));
  1422. X#endif
  1423. X    kill(0,signo);        /* and do the stop */
  1424. X        savetty();
  1425. X#ifdef MAILCALL
  1426. X        mailcount = 0;            /* force recheck */
  1427. X#endif
  1428. X        if (!panic) {
  1429. X        if (!waiting) {
  1430. X            noecho();            /* set no echo */
  1431. X            crmode();            /* set cbreak mode */
  1432. X            forceme("\f");        /* cause a refresh */
  1433. X                    /* (defined only if TIOCSTI defined) */
  1434. X        errno = 0;            /* needed for getcmd */
  1435. X        }
  1436. X        }
  1437. X    }
  1438. X    sigset(signo,stop_catcher);    /* unenable the stop */
  1439. X}
  1440. X#endif
  1441. END_OF_FILE
  1442.   if test 5537 -ne `wc -c <'final.c'`; then
  1443.     echo shar: \"'final.c'\" unpacked with wrong size!
  1444.   fi
  1445.   # end of 'final.c'
  1446. fi
  1447. if test -f 'kfile.c' -a "${1}" != "-c" ; then 
  1448.   echo shar: Will not clobber existing file \"'kfile.c'\"
  1449. else
  1450.   echo shar: Extracting \"'kfile.c'\" \(7358 characters\)
  1451.   sed "s/^X//" >'kfile.c' <<'END_OF_FILE'
  1452. X/* $Header: kfile.c,v 4.3.3.2 91/01/16 02:46:28 davison Trn $
  1453. X *
  1454. X * $Log:    kfile.c,v $
  1455. X * Revision 4.3.3.2  91/01/16  02:46:28  davison
  1456. X * Integrated rn patches 48-54.
  1457. X * 
  1458. X * Revision 4.3.3.1  90/06/20  22:38:06  davison
  1459. X * Initial Trn Release
  1460. X * 
  1461. X * Revision 4.3.2.2  90/11/22  16:09:54  sob
  1462. X * Added changes to accomodate picky C preprocessors
  1463. X * 
  1464. X * Revision 4.3.2.1  90/03/22  23:04:41  sob
  1465. X * Fixes provided by Wayne Davison <drivax!davison>
  1466. X * 
  1467. X * Revision 4.3.1.3  85/05/29  09:11:52  lwall
  1468. X * Suppressed some killing messages on -t.
  1469. X * 
  1470. X * Revision 4.3.1.2  85/05/10  14:21:29  lwall
  1471. X * Prevented THRU from setting art < absfirst.
  1472. X * 
  1473. X * Revision 4.3.1.1  85/05/10  11:34:33  lwall
  1474. X * Branch for patches.
  1475. X * 
  1476. X * Revision 4.3  85/05/01  11:41:53  lwall
  1477. X * Baseline for release with 4.3bsd.
  1478. X * 
  1479. X */
  1480. X
  1481. X#include "EXTERN.h"
  1482. X#include "common.h"
  1483. X#include "term.h"
  1484. X#include "util.h"
  1485. X#include "artsrch.h"
  1486. X#include "ng.h"
  1487. X#include "bits.h"
  1488. X#include "intrp.h"
  1489. X#include "ngstuff.h"
  1490. X#include "rcstuff.h"
  1491. X#include "rn.h"
  1492. X#ifdef USETHREADS
  1493. X#include "rthreads.h"
  1494. X#endif
  1495. X#include "INTERN.h"
  1496. X#include "kfile.h"
  1497. X
  1498. Xstatic bool exitcmds = FALSE;
  1499. X
  1500. Xvoid
  1501. Xkfile_init()
  1502. X{
  1503. X    ;
  1504. X}
  1505. X
  1506. X#ifndef KILLFILES
  1507. Xint
  1508. Xedit_kfile()
  1509. X{
  1510. X    notincl("^K");
  1511. X    return -1;
  1512. X}
  1513. X
  1514. X#else /* KILLFILES */
  1515. X
  1516. Xchar killglobal[] = KILLGLOBAL;
  1517. Xchar killlocal[] = KILLLOCAL;
  1518. X
  1519. Xvoid
  1520. Xmention(str)
  1521. Xchar *str;
  1522. X{
  1523. X#ifdef VERBOSE
  1524. X    IF(verbose) {
  1525. X#ifdef NOFIREWORKS
  1526. X    no_sofire();
  1527. X#endif
  1528. X    standout();
  1529. X    fputs(str,stdout);
  1530. X    un_standout();
  1531. X    putchar('\n');
  1532. X    }
  1533. X    ELSE
  1534. X#endif
  1535. X#ifdef TERSE
  1536. X    putchar('.');
  1537. X#endif
  1538. X    fflush(stdout);
  1539. X}
  1540. X
  1541. Xbool kill_mentioned;
  1542. X
  1543. Xint
  1544. Xdo_kfile(kfp,entering)
  1545. XFILE *kfp;
  1546. Xint entering;
  1547. X{
  1548. X#ifdef USETHREADS
  1549. X    int i;
  1550. X    ART_NUM kill_thread;
  1551. X#endif
  1552. X
  1553. X    art = lastart+1;
  1554. X    fseek(kfp,0L,0);            /* rewind file */
  1555. X    while (fgets(buf,LBUFLEN,kfp) != Nullch) {
  1556. X    buf[strlen(buf)-1] = '\0';
  1557. X    if (strnEQ(buf,"THRU",4)) {
  1558. X        ART_NUM tmpart;
  1559. X
  1560. X        tmpart = atol(buf+4)+1;
  1561. X        if (tmpart < absfirst)
  1562. X        tmpart = absfirst;
  1563. X        check_first(tmpart);
  1564. X        firstart = tmpart;
  1565. X        continue;
  1566. X    }
  1567. X    if (*buf == 'X') {        /* exit command? */
  1568. X        if (entering) {
  1569. X        exitcmds = TRUE;
  1570. X        continue;
  1571. X        }
  1572. X        strcpy(buf,buf+1);
  1573. X    }
  1574. X    else {
  1575. X        if (!entering)
  1576. X        continue;
  1577. X    }
  1578. X    if (*buf == '&') {
  1579. X        mention(buf);
  1580. X        switcheroo();
  1581. X    }
  1582. X    else if (*buf == '/' && firstart <= lastart) {
  1583. X        mention(buf);
  1584. X        kill_mentioned = TRUE;
  1585. X        switch (art_search(buf, (sizeof buf), FALSE)) {
  1586. X        case SRCH_ABORT:
  1587. X        continue;
  1588. X        case SRCH_INTR:
  1589. X#ifdef VERBOSE
  1590. X        IF(verbose)
  1591. X            printf("\n(Interrupted at article %ld)\n",(long)art)
  1592. X              FLUSH;
  1593. X        ELSE
  1594. X#endif
  1595. X#ifdef TERSE
  1596. X            printf("\n(Intr at %ld)\n",(long)art) FLUSH;
  1597. X#endif
  1598. X        return -1;
  1599. X        case SRCH_DONE:
  1600. X        break;
  1601. X        case SRCH_SUBJDONE:
  1602. X        fputs("\tsubject not found (???)\n",stdout) FLUSH;
  1603. X        break;
  1604. X        case SRCH_NOTFOUND:
  1605. X        fputs("\tnot found\n",stdout) FLUSH;
  1606. X        break;
  1607. X        case SRCH_FOUND:
  1608. X        fputs("\tfound\n",stdout) FLUSH;
  1609. X        }
  1610. X    }
  1611. X#ifdef USETHREADS
  1612. X    else if (*buf == 'T' && firstart <= lastart && p_roots) {
  1613. X        /* kill a thread by its root id number */
  1614. X        kill_thread = atol(buf+1);
  1615. X        for (i = 0; i < total.root; i++) {
  1616. X        if (p_roots[i].root_num == kill_thread) {
  1617. X            if (count_one_root(i) != 0) {
  1618. X            mention(buf);
  1619. X            kill_mentioned = TRUE;
  1620. X            printf("%ldx%d ",(long)kill_thread,
  1621. X                     root_article_cnts[i]);
  1622. X            p_art = p_articles + p_roots[i].articles;
  1623. X            art = p_art->num;
  1624. X            follow_thread('k');
  1625. X            }
  1626. X            break;
  1627. X        }
  1628. X        }
  1629. X    }
  1630. X#endif
  1631. X    }
  1632. X
  1633. X    return 0;
  1634. X}
  1635. X
  1636. Xvoid
  1637. Xkill_unwanted(starting,message,entering)
  1638. XART_NUM starting;
  1639. Xchar *message;
  1640. Xint entering;
  1641. X{
  1642. X    bool intr = FALSE;            /* did we get an interrupt? */
  1643. X    ART_NUM oldfirst;
  1644. X    bool anytokill = (toread[ng] > 0);
  1645. X
  1646. X    if (localkfp || globkfp) {
  1647. X    if (!entering && !exitcmds)
  1648. X        return;
  1649. X    exitcmds = FALSE;
  1650. X    oldfirst = firstart;
  1651. X    firstart = starting;
  1652. X    clear();
  1653. X#ifdef VERBOSE
  1654. X# ifdef TERSE
  1655. X    if (message && (verbose || entering))
  1656. X# else
  1657. X    if (message)
  1658. X# endif
  1659. X#else
  1660. X    if (message && entering)
  1661. X#endif
  1662. X        fputs(message,stdout) FLUSH;
  1663. X
  1664. X    kill_mentioned = FALSE;
  1665. X    if (localkfp)
  1666. X        intr = do_kfile(localkfp,entering);
  1667. X    if (globkfp && !intr)
  1668. X        intr = do_kfile(globkfp,entering);
  1669. X    if (entering && localkfp && !intr)
  1670. X        setthru(lastart);
  1671. X    putchar('\n') FLUSH;
  1672. X    if (entering && kill_mentioned)
  1673. X#ifdef VERBOSE
  1674. X        IF(verbose)
  1675. X        get_anything();
  1676. X        ELSE
  1677. X#endif
  1678. X#ifdef TERSE
  1679. X        pad(just_a_sec);
  1680. X#endif
  1681. X    if (anytokill)            /* if there was anything to kill */
  1682. X        forcelast = FALSE;        /* allow for having killed it all */
  1683. X    firstart = oldfirst;
  1684. X    }
  1685. X}
  1686. X
  1687. Xvoid
  1688. Xsetthru(thru)
  1689. XART_NUM thru;
  1690. X{
  1691. X    FILE *newkfp;
  1692. X    bool no_kills = 0;
  1693. X#ifdef USETHREADS
  1694. X    int i;
  1695. X    ART_NUM kill_thread;
  1696. X#endif
  1697. X
  1698. X    fseek(localkfp,0L,0);        /* rewind current file */
  1699. X    if (fgets(buf,LBUFLEN,localkfp) != Nullch
  1700. X     && (strnNE(buf,"THRU",4) || fgets(buf,LBUFLEN,localkfp) != Nullch))
  1701. X    fseek(localkfp,0L,0);
  1702. X    else
  1703. X    no_kills = 1;
  1704. X    strcpy(buf,filexp(getval("KILLLOCAL",killlocal)));
  1705. X    UNLINK(buf);            /* to prevent file reuse */
  1706. X    if (no_kills)
  1707. X    open_kfile(KF_LOCAL);        /* close file and reset open flag */
  1708. X    else if (newkfp = fopen(buf,"w")) {
  1709. X    fprintf(newkfp,"THRU %ld\n",(long)thru);
  1710. X    while (fgets(buf,LBUFLEN,localkfp) != Nullch) {
  1711. X        if (strnEQ(buf,"THRU",4))
  1712. X        continue;
  1713. X#ifdef USETHREADS
  1714. X        /* Leave out any outdated thread kills */
  1715. X        if (*buf == 'T' && p_roots) {
  1716. X        kill_thread = atol(buf+1);
  1717. X        for (i = 0; i < total.root; i++) {
  1718. X            if (p_roots[i].root_num == kill_thread) {
  1719. X            break;
  1720. X            }
  1721. X        }
  1722. X        if (i == total.root)
  1723. X            continue;
  1724. X        }
  1725. X#endif
  1726. X        fputs(buf,newkfp);
  1727. X    }
  1728. X    fclose(newkfp);
  1729. X    open_kfile(KF_LOCAL);        /* and reopen local file */
  1730. X    }
  1731. X    else
  1732. X    printf(cantcreate,buf) FLUSH;
  1733. X}
  1734. X
  1735. X/* edit KILL file for newsgroup */
  1736. X
  1737. Xint
  1738. Xedit_kfile()
  1739. X{
  1740. X    int r = -1;
  1741. X
  1742. X    if (in_ng)
  1743. X    strcpy(buf,filexp(getval("KILLLOCAL",killlocal)));
  1744. X    else
  1745. X    strcpy(buf,filexp(getval("KILLGLOBAL",killglobal)));
  1746. X    if ((r = makedir(buf,MD_FILE)) >= 0) {
  1747. X    sprintf(cmd_buf,"%s %s",
  1748. X        filexp(getval("VISUAL",getval("EDITOR",defeditor))),buf);
  1749. X    printf("\nEditing %s KILL file:\n%s\n",
  1750. X        (in_ng?"local":"global"),cmd_buf) FLUSH;
  1751. X    resetty();            /* make sure tty is friendly */
  1752. X    r = doshell(sh,cmd_buf);/* invoke the shell */
  1753. X    noecho();            /* and make terminal */
  1754. X    crmode();            /*   unfriendly again */
  1755. X    open_kfile(in_ng);
  1756. X    }
  1757. X    else
  1758. X    printf("Can't make %s\n",buf) FLUSH;
  1759. X    return r;
  1760. X}
  1761. X
  1762. Xvoid
  1763. Xopen_kfile(local)
  1764. Xint local;
  1765. X{
  1766. X    char *kname = filexp(local ?
  1767. X    getval("KILLLOCAL",killlocal) :
  1768. X    getval("KILLGLOBAL",killglobal)
  1769. X    );
  1770. X    
  1771. X    stat(kname,&filestat);
  1772. X    if (!filestat.st_size)        /* nothing in the file? */
  1773. X    UNLINK(kname);            /* delete the file */
  1774. X    if (local) {
  1775. X    if (localkfp)
  1776. X        fclose(localkfp);
  1777. X    localkfp = fopen(kname,"r");
  1778. X    }
  1779. X    else {
  1780. X    if (globkfp)
  1781. X        fclose(globkfp);
  1782. X    globkfp = fopen(kname,"r");
  1783. X    }
  1784. X}
  1785. X
  1786. Xvoid
  1787. Xkf_append(cmd)
  1788. Xchar *cmd;
  1789. X{
  1790. X    strcpy(cmd_buf,filexp(getval("KILLLOCAL",killlocal)));
  1791. X    if (makedir(cmd_buf,MD_FILE) >= 0) {
  1792. X#ifdef VERBOSE
  1793. X    IF(verbose)
  1794. X        printf("\nDepositing command in %s...",cmd_buf);
  1795. X    ELSE
  1796. X#endif
  1797. X#ifdef TERSE
  1798. X        printf("\n--> %s...",cmd_buf);
  1799. X#endif
  1800. X    fflush(stdout);
  1801. X    sleep(2);
  1802. X    if ((tmpfp = fopen(cmd_buf,"a")) != Nullfp) {
  1803. X        fseek(tmpfp,0L,2);        /* get to EOF for sure */
  1804. X        fprintf(tmpfp,"%s\n",cmd);
  1805. X        fclose(tmpfp);
  1806. X        fputs("done\n",stdout) FLUSH;
  1807. X    }
  1808. X    else
  1809. X        printf(cantopen,cmd_buf) FLUSH;
  1810. X    }
  1811. X}
  1812. X#endif /* KILLFILES */
  1813. END_OF_FILE
  1814.   if test 7358 -ne `wc -c <'kfile.c'`; then
  1815.     echo shar: \"'kfile.c'\" unpacked with wrong size!
  1816.   fi
  1817.   # end of 'kfile.c'
  1818. fi
  1819. if test -f 'rthreads.c' -a "${1}" != "-c" ; then 
  1820.   echo shar: Will not clobber existing file \"'rthreads.c'\"
  1821. else
  1822.   echo shar: Extracting \"'rthreads.c'\" \(7151 characters\)
  1823.   sed "s/^X//" >'rthreads.c' <<'END_OF_FILE'
  1824. X/* $Header: rthreads.c,v 4.3.3.3 91/01/16 03:28:53 davison Trn $
  1825. X**
  1826. X** $Log:    rthreads.c,v $
  1827. X** Revision 4.3.3.3  91/01/16  03:28:53  davison
  1828. X** Changed Free to safefree.  Tweaked fopen for possible binary open mode.
  1829. X** 
  1830. X** Revision 4.3.3.2  90/08/20  16:58:14  davison
  1831. X** Added message for missing/bad db.init file.
  1832. X** 
  1833. X** Revision 4.3.3.1  90/06/20  23:00:28  davison
  1834. X** Initial Trn Release
  1835. X** 
  1836. X*/
  1837. X
  1838. X#include "EXTERN.h"
  1839. X#include "common.h"
  1840. X#include "intrp.h"
  1841. X
  1842. X#ifdef USETHREADS
  1843. X#include "INTERN.h"
  1844. X#include "rthreads.h"
  1845. X
  1846. Xstatic FILE *fp_in;
  1847. X
  1848. Xstatic char *strings = Nullch;
  1849. X
  1850. Xstatic int read_item();
  1851. Xstatic void wp_bmap(), lp_bmap();
  1852. Xstatic void safefree();
  1853. X
  1854. X/* Initialize our thread code by determining the byte-order of the thread
  1855. X** files and our own current byte-order.  If they differ, set flags to let
  1856. X** the read code know what we'll need to translate.
  1857. X*/
  1858. Xvoid
  1859. Xthread_init()
  1860. X{
  1861. X    char *filename;
  1862. X    int i;
  1863. X
  1864. X    word_same = long_same = TRUE;
  1865. X    filename = filexp( "%X/db.init" );
  1866. X    if( (fp_in = fopen( filename, FOPEN_RB )) != Nullfp ) {
  1867. X    if( fread( &mt_bmap, 1, sizeof (BMAP), fp_in ) >= sizeof (BMAP)-1 ) {
  1868. X        if( mt_bmap.version != DB_VERSION ) {
  1869. X        printf( "\nThread database is the wrong version -- ignoring it.\n" ) FLUSH;
  1870. X        use_threads = FALSE;
  1871. X        }
  1872. X        mybytemap( &my_bmap );
  1873. X        for( i = 0; i < sizeof (LONG); i++ ) {
  1874. X        if( i < sizeof (WORD) ) {
  1875. X            if( my_bmap.w[i] != mt_bmap.w[i] ) {
  1876. X            word_same = FALSE;
  1877. X            }
  1878. X        }
  1879. X        if( my_bmap.l[i] != mt_bmap.l[i] ) {
  1880. X            long_same = FALSE;
  1881. X        }
  1882. X        }
  1883. X    } else {
  1884. X        goto no_db_init;
  1885. X    }
  1886. X    fclose( fp_in );
  1887. X    } else {
  1888. X      no_db_init:
  1889. X    printf( "\ndb.init read failed -- assuming no byte-order translations.\n\n" ) FLUSH;
  1890. X    }
  1891. X}
  1892. X
  1893. X/* Open a thread file for the sole purpose of using it in a newsreader-
  1894. X** style application.  Everything is read into arrays in chunks and some
  1895. X** useful massaging of the data is performed to make the newsreader's life
  1896. X** easier.  Be sure to call unuse_data() before calling this a second time.
  1897. X*/
  1898. Xint
  1899. Xuse_data( threadname )
  1900. Xchar *threadname;
  1901. X{
  1902. X    register int i, j, k;
  1903. X    register char *ptr;
  1904. X
  1905. X    if( (fp_in = fopen( threadname, FOPEN_RB )) == Nullfp ) {
  1906. X    if (errno != ENOENT) {
  1907. X        printf( "\n\nOpen failed for thread data -- continuing unthreaded.\n" );
  1908. X    }
  1909. X    bzero( &total, sizeof (TOTAL) );
  1910. X    return 0;
  1911. X    }
  1912. X    if( fread( &total, 1, sizeof (TOTAL), fp_in ) < sizeof (TOTAL) ) {
  1913. X    printf( "\n\nRead failed for thread data -- continuing unthreaded.\n" );
  1914. X    fclose( fp_in );
  1915. X    bzero( &total, sizeof (TOTAL) );
  1916. X    return 0;
  1917. X    }
  1918. X    lp_bmap( &total.first, 4 );
  1919. X    wp_bmap( &total.root, 5 );
  1920. X
  1921. X    if( !read_item( &author_cnts, (MEM_SIZE)total.author * sizeof (WORD) )
  1922. X     || !read_item( &strings, (MEM_SIZE)total.string1 ) 
  1923. X     || !read_item( &subject_cnts, (MEM_SIZE)total.subject * sizeof (WORD) )
  1924. X     || !read_item( &p_roots, (MEM_SIZE)total.root * sizeof (PACKED_ROOT) )
  1925. X     || !read_item( &p_articles, (MEM_SIZE)total.article * sizeof (PACKED_ARTICLE) ) ) {
  1926. X    printf( "\n\nRead failed for thread data -- continuing unthreaded.\n" );
  1927. X    fclose( fp_in );
  1928. X    unuse_data( 0 );
  1929. X    return 0;
  1930. X    }
  1931. X    fclose( fp_in );
  1932. X
  1933. X    if( !word_same || !long_same ) {
  1934. X    wp_bmap( author_cnts, total.author );
  1935. X    wp_bmap( subject_cnts, total.subject );
  1936. X    for( i = 0; i < total.root; i++ ) {
  1937. X        lp_bmap( &p_roots[i].root_num, 1 );
  1938. X        wp_bmap( &p_roots[i].articles, 3 );
  1939. X    }
  1940. X    for( i = 0; i < total.article; i++ ) {
  1941. X        lp_bmap( &p_articles[i].num, 2 );
  1942. X        wp_bmap( &p_articles[i].subject, 8 );
  1943. X    }
  1944. X    }
  1945. X
  1946. X#ifndef lint
  1947. X    author_ptrs = (char **)safemalloc( total.author * sizeof (char **) );
  1948. X    subject_ptrs = (char **)safemalloc( total.subject * sizeof (char **) );
  1949. X    root_subjects = (WORD *)safemalloc( total.root * sizeof (WORD) );
  1950. X    root_article_cnts = (WORD *)safemalloc( total.root * sizeof (WORD) );
  1951. X#endif
  1952. X    selected_roots = safemalloc( total.root * sizeof (char) );
  1953. X
  1954. X    bzero( root_article_cnts, total.root * sizeof (WORD) );
  1955. X    bzero( selected_roots, total.root * sizeof (char) );
  1956. X
  1957. X    for( i = 0, ptr = strings; i < total.author; i++ ) {
  1958. X    author_ptrs[i] = ptr;
  1959. X    ptr += strlen( ptr ) + 1;
  1960. X    }
  1961. X
  1962. X    for( i = 0, j = 0; i < total.root; i++ ) {
  1963. X    root_subjects[i] = j;
  1964. X    k = p_roots[i].subject_cnt;
  1965. X    while( k-- ) {
  1966. X        root_article_cnts[i] += subject_cnts[j];
  1967. X        subject_ptrs[j++] = ptr;
  1968. X        ptr += strlen( ptr ) + 1;
  1969. X    }
  1970. X    if( saved_selections ) {
  1971. X        for( k = 0; k < selected_root_cnt; k++ ) {
  1972. X        if( p_roots[i].root_num == saved_selections[k] ) {
  1973. X            selected_roots[i] = 1;
  1974. X        }
  1975. X        }
  1976. X    }
  1977. X    }
  1978. X    count_roots( !saved_selections );
  1979. X    safefree( &saved_selections );
  1980. X    select_page = 0;
  1981. X    return 1;
  1982. X}
  1983. X
  1984. X/* A short-hand for reading a chunk of the file into a malloced array.
  1985. X*/
  1986. Xstatic int
  1987. Xread_item( dest, len )
  1988. Xchar **dest;
  1989. XMEM_SIZE len;
  1990. X{
  1991. X    int ret;
  1992. X
  1993. X    *dest = safemalloc( len );
  1994. X    ret = fread( *dest, 1, (int)len, fp_in );
  1995. X    if( ret != len ) {
  1996. X    free( *dest );
  1997. X    *dest = Nullch;
  1998. X    return 0;
  1999. X    }
  2000. X    return 1;
  2001. X}
  2002. X
  2003. X/* Free some memory if it hasn't already been freed.
  2004. X*/
  2005. Xstatic void
  2006. Xsafefree( pp )
  2007. Xchar **pp;
  2008. X{
  2009. X    if( *pp ) {
  2010. X    free( *pp );
  2011. X    *pp = Nullch;
  2012. X    }
  2013. X}
  2014. X
  2015. X/* Discard the thread data that we received through the use_data() call.
  2016. X** If "save_selections" is non-zero, we'll try to remember which roots
  2017. X** are currently selected long enough for the use_data() call to re-use
  2018. X** them.  Only do this when you are going to re-open the same data file
  2019. X** immediately with use_data() (presumably because the data has been
  2020. X** updated while we were using it).
  2021. X*/
  2022. Xvoid
  2023. Xunuse_data( save_selections )
  2024. Xbool save_selections;
  2025. X{
  2026. X    int i, j;
  2027. X
  2028. X    if( save_selections ) {
  2029. X#ifndef lint
  2030. X    saved_selections
  2031. X      = (ART_NUM *)safemalloc( selected_root_cnt * sizeof (ART_NUM) );
  2032. X#endif
  2033. X    for( i = 0, j = 0; i < total.root; i++ ) {
  2034. X        if( selected_roots[i] && root_article_cnts[i] ) {
  2035. X        saved_selections[j++] = p_roots[i].root_num;
  2036. X        }
  2037. X    }
  2038. X    } else {
  2039. X    selected_root_cnt = selected_count = 0;
  2040. X    }
  2041. X    safefree( &p_roots );
  2042. X    safefree( &root_subjects );
  2043. X    safefree( &author_cnts );
  2044. X    safefree( &subject_cnts );
  2045. X    safefree( &author_ptrs );
  2046. X    safefree( &subject_ptrs );
  2047. X    safefree( &root_article_cnts );
  2048. X    safefree( &selected_roots );
  2049. X    safefree( &p_articles );
  2050. X    safefree( &strings );
  2051. X
  2052. X    p_art = curr_p_art = Nullart;
  2053. X    init_tree();        /* free any tree lines */
  2054. X
  2055. X    bzero( &total, sizeof (TOTAL) );
  2056. X}
  2057. X
  2058. X/* Transform each WORD's byte-ordering in a buffer of the designated length.
  2059. X*/
  2060. Xstatic void
  2061. Xwp_bmap( buf, len )
  2062. XWORD *buf;
  2063. Xint len;
  2064. X{
  2065. X    union {
  2066. X    BYTE b[sizeof (WORD)];
  2067. X    WORD w;
  2068. X    } in, out;
  2069. X    register int i;
  2070. X
  2071. X    if( word_same ) {
  2072. X    return;
  2073. X    }
  2074. X    while( len-- ) {
  2075. X    in.w = *buf;
  2076. X    for( i = 0; i < sizeof (WORD); i++ ) {
  2077. X        out.b[my_bmap.w[i]] = in.b[mt_bmap.w[i]];
  2078. X    }
  2079. X    *buf++ = out.w;
  2080. X    }
  2081. X}
  2082. X
  2083. X/* Transform each LONG's byte-ordering in a buffer of the designated length.
  2084. X*/
  2085. Xstatic void
  2086. Xlp_bmap( buf, len )
  2087. XLONG *buf;
  2088. Xint len;
  2089. X{
  2090. X    union {
  2091. X    BYTE b[sizeof (LONG)];
  2092. X    LONG l;
  2093. X    } in, out;
  2094. X    register int i;
  2095. X
  2096. X    if( long_same ) {
  2097. X    return;
  2098. X    }
  2099. X    while( len-- ) {
  2100. X    in.l = *buf;
  2101. X    for( i = 0; i < sizeof (LONG); i++ ) {
  2102. X        out.b[my_bmap.l[i]] = in.b[mt_bmap.l[i]];
  2103. X    }
  2104. X    *buf++ = out.l;
  2105. X    }
  2106. X}
  2107. X
  2108. X#endif /* USETHREADS */
  2109. END_OF_FILE
  2110.   if test 7151 -ne `wc -c <'rthreads.c'`; then
  2111.     echo shar: \"'rthreads.c'\" unpacked with wrong size!
  2112.   fi
  2113.   # end of 'rthreads.c'
  2114. fi
  2115. if test -f 'uudecode.c' -a "${1}" != "-c" ; then 
  2116.   echo shar: Will not clobber existing file \"'uudecode.c'\"
  2117. else
  2118.   echo shar: Extracting \"'uudecode.c'\" \(8069 characters\)
  2119.   sed "s/^X//" >'uudecode.c' <<'END_OF_FILE'
  2120. X/* $Header: uudecode.c,v 4.3.3.2 91/01/16 03:41:52 davison Trn $
  2121. X**
  2122. X** $Log:    uudecode.c,v $
  2123. X** Revision 4.3.3.2  91/01/16  03:41:52  davison
  2124. X** Tweaked fopen for possible binary open mode.
  2125. X** 
  2126. X** Revision 4.3.3.1  90/06/20  22:48:21  davison
  2127. X** Initial Trn Release
  2128. X** 
  2129. X** Decode one or more uuencoded articles back to binary form.
  2130. X**
  2131. X** Trn version created by Wayne Davison.
  2132. X** Adapted from the nn version by Kim Storm.
  2133. X** From the Berkeley original, modified by MSD, RDR, JPHD & WLS.
  2134. X*/
  2135. X
  2136. X#include "EXTERN.h"
  2137. X#include "common.h"
  2138. X#include "INTERN.h"
  2139. X#include "uudecode.h"
  2140. X
  2141. X#if 000
  2142. Xexport char *decode_header_file = "Decode.Headers";
  2143. X#endif
  2144. X
  2145. X#define MAXCHAR 256
  2146. X#define NORMLEN 60    /* allows for 80 encoded chars per line */
  2147. X
  2148. X#define SEQMAX 'z'
  2149. X#define SEQMIN 'a'
  2150. X
  2151. Xstatic char seqc;
  2152. Xstatic int first, secnd, check, numl;
  2153. X
  2154. Xstatic char *target;
  2155. Xstatic char dest[MAXFILENAME];
  2156. Xstatic char blank;
  2157. Xstatic int chtbl[MAXCHAR], cdlen[NORMLEN + 3];
  2158. Xstatic int state;
  2159. Xstatic bool Xflag;
  2160. X
  2161. X#define    NO_ADVANCE        0x10
  2162. X
  2163. X#define    FIND_BEGIN        0x01
  2164. X#define    FIND_BEGIN_AFTER_ERROR    0x02
  2165. X#define    DECODE_TEXT        0x03
  2166. X#define    SKIP_TRAILING           (0x04 | NO_ADVANCE)
  2167. X#define    SKIP_LEADING        0x05
  2168. X#define    FOUND_END           (0x06 | NO_ADVANCE)
  2169. X#define DECODE_ERROR           (0x07 | NO_ADVANCE)
  2170. X#define OTHER_ERROR           (0x08 | NO_ADVANCE)
  2171. X#define NEW_BEGIN           (0x09 | NO_ADVANCE)
  2172. X
  2173. Xuud_start(dir)
  2174. Xchar *dir;
  2175. X{
  2176. X    target = dir;
  2177. X    uu_out = Nullfp;
  2178. X    Xflag = FALSE;
  2179. X    seqc = SEQMAX;
  2180. X    check = 1;
  2181. X    first = 1;
  2182. X    secnd = 0;
  2183. X    state = FIND_BEGIN;
  2184. X}
  2185. X
  2186. Xuud_end()
  2187. X{
  2188. X    if (uu_out != Nullfp) {
  2189. X    fclose(uu_out);
  2190. X    uu_out = Nullfp;
  2191. X    printf("\n%s INCOMPLETE -- removed\n", dest);
  2192. X    unlink(dest);
  2193. X    }
  2194. X}
  2195. X
  2196. X
  2197. Xuudecode(in)
  2198. XFILE *in;
  2199. X{
  2200. X    int mode, onedone, lens;
  2201. X    char buff[LBUFLEN];
  2202. X
  2203. X    numl = onedone = 0;
  2204. X
  2205. X    if (state == FIND_BEGIN)
  2206. X    inittbls();
  2207. X
  2208. X    /*
  2209. X     * search for header or translation table line.
  2210. X     */
  2211. X
  2212. X    while ((state & NO_ADVANCE) || fgets(buff, sizeof buff, in) != Nullch) {
  2213. X    numl++;
  2214. X
  2215. X    switch (state) {
  2216. X     case NEW_BEGIN:
  2217. X        if (uu_out != Nullfp) {
  2218. X        printf("INCOMPLETE FILE: %s -- removed\n", dest);
  2219. X        sleep(2);
  2220. X        fclose(uu_out);
  2221. X        uu_out = Nullfp;
  2222. X        Xflag = FALSE;
  2223. X        unlink(dest);
  2224. X        }
  2225. X        /* fall thru */
  2226. X
  2227. X     case FIND_BEGIN:
  2228. X     case FIND_BEGIN_AFTER_ERROR:
  2229. X        if (strnEQ(buff, "table ", 6)) {
  2230. X        gettable(in);
  2231. X        continue;
  2232. X        }
  2233. X
  2234. X        if (strnEQ(buff, "begin ", 6)
  2235. X         || strnEQ(buff, "Xbegin ", 7)) {
  2236. X        lens = strlen(buff)-1;
  2237. X        if (buff[lens] == '\n')
  2238. X            buff[lens] = '\0';
  2239. X
  2240. X        if(sscanf(buff+6,"%o%s", &mode, uu_fname) != 2)
  2241. X            continue;
  2242. X
  2243. X        Xflag = (*buff == 'X');
  2244. X
  2245. X        if (target != Nullch)
  2246. X            sprintf(dest, "%s/%s", target, uu_fname);
  2247. X        else
  2248. X            strcpy(dest, uu_fname);
  2249. X
  2250. X        if ((uu_out = fopen(dest, FOPEN_WB)) == Nullfp) {
  2251. X            printf("Cannot create file: %s\n", dest);
  2252. X            goto err;
  2253. X        }
  2254. X        chmod(dest, mode);
  2255. X
  2256. X#if 000
  2257. X        if (decode_header_file)
  2258. X            store_header(ah, in, target, decode_header_file);
  2259. X#endif
  2260. X
  2261. X        printf("Decoding: %s\n", uu_fname);
  2262. X        state = DECODE_TEXT;
  2263. X        }
  2264. X        continue;
  2265. X
  2266. X     case SKIP_LEADING:
  2267. X        state = decode_line(buff);
  2268. X        continue;
  2269. X
  2270. X     case DECODE_TEXT:
  2271. X        state = decode_line(buff);
  2272. X        onedone = 1;
  2273. X        continue;
  2274. X
  2275. X     case FOUND_END:
  2276. X        fclose(uu_out);
  2277. X        uu_out = Nullfp;
  2278. X        Xflag = FALSE;
  2279. X        state = FIND_BEGIN;
  2280. X        printf("Done.\n");
  2281. X        continue;
  2282. X
  2283. X     case SKIP_TRAILING:
  2284. X        printf("(Continued)\n");
  2285. X        state = SKIP_LEADING;
  2286. X        return 0;
  2287. X
  2288. X     case DECODE_ERROR:
  2289. X        state = SKIP_TRAILING;
  2290. X        continue;
  2291. X
  2292. X     case OTHER_ERROR:
  2293. X        fclose(uu_out);
  2294. X        uu_out = Nullfp;
  2295. X        Xflag = FALSE;
  2296. X        state = FIND_BEGIN_AFTER_ERROR;
  2297. X        goto err;
  2298. X    }
  2299. X    }
  2300. X
  2301. X    if (onedone) {
  2302. X    if (state == DECODE_TEXT)
  2303. X        state = SKIP_LEADING;
  2304. X    return 0;
  2305. X    }
  2306. X
  2307. X    if (state == FIND_BEGIN_AFTER_ERROR)
  2308. X    return -1;
  2309. X    printf("Couldn't find anything to decode.\n");
  2310. X
  2311. X err:
  2312. X    sleep(2);
  2313. X    return -1;
  2314. X}
  2315. X
  2316. X/*
  2317. X * decode one line, write on uu_out file
  2318. X */
  2319. X
  2320. Xstatic decode_line(buff)
  2321. Xchar *buff;
  2322. X{
  2323. X    char outl[LBUFLEN];
  2324. X    register char *bp, *ut;
  2325. X    register int *trtbl = chtbl;
  2326. X    register int n;
  2327. X    register int blen;        /* binary length (from decoded file) */
  2328. X    register int rlen;        /* calculated input line length */
  2329. X    register int len;        /* actual input line length */
  2330. X
  2331. X    if (Xflag) {
  2332. X    if (*buff == 'X')
  2333. X        buff++;
  2334. X    else
  2335. X        *buff = 'x';    /* force a mis-parse of a non-x'ed line */
  2336. X    }
  2337. X    len = strlen(buff);
  2338. X    if (--len < 0)
  2339. X    return state;
  2340. X
  2341. X    buff[len] = '\0';
  2342. X
  2343. X    /*
  2344. X     * Get the binary line length.
  2345. X     */
  2346. X    if ((blen = trtbl[buff[0]]) < 0) {
  2347. X    if (state == SKIP_LEADING) {
  2348. X        if (strnEQ(buff, "begin ", 6))
  2349. X        return NEW_BEGIN;
  2350. X
  2351. X        return SKIP_LEADING;
  2352. X    }
  2353. X    /*
  2354. X     * end of uuencoded file ?
  2355. X     */
  2356. X    if (strnEQ(buff, "end", 3))
  2357. X        return FOUND_END;
  2358. X
  2359. X    /*
  2360. X     * end of current file ? : get next one.
  2361. X     */
  2362. X    if (strnEQ(buff, "include", 7)) {
  2363. X        printf("Cannot handle 'include' lines -- unpack with uud\n");
  2364. X        return OTHER_ERROR;
  2365. X    }
  2366. X
  2367. X    /*
  2368. X     * trailing garbage
  2369. X     */
  2370. X    return SKIP_TRAILING;
  2371. X    }
  2372. X
  2373. X    rlen = cdlen[blen];
  2374. X    if (state == SKIP_LEADING && len != rlen && len != rlen+1)
  2375. X    return SKIP_LEADING;
  2376. X
  2377. X    /*
  2378. X     * Is it the empty line before the end line ?
  2379. X     */
  2380. X    if (blen == 0)
  2381. X    return state;
  2382. X
  2383. X    if (len > rlen + 5)
  2384. X    return SKIP_TRAILING;
  2385. X
  2386. X    /*
  2387. X     * Pad with blanks.
  2388. X     */
  2389. X    for (bp = buff + len, n = rlen - len; --n >= 0; )
  2390. X    *bp++ = blank;
  2391. X
  2392. X    /*
  2393. X     * Verify
  2394. X     */
  2395. X    for (n = rlen, bp = buff; --n >= 0; bp++)
  2396. X    if (trtbl[*bp] < 0) {
  2397. X        if (state == SKIP_LEADING)
  2398. X        return SKIP_LEADING;
  2399. X        return DECODE_ERROR;
  2400. X    }
  2401. X
  2402. X    /*
  2403. X     * Check for uuencodes that append a 'z' to each line....
  2404. X     */
  2405. X    if (check)
  2406. X    if (secnd) {
  2407. X        secnd = 0;
  2408. X        if (buff[rlen] == SEQMAX)
  2409. X        check = 0;
  2410. X    } else if (first) {
  2411. X        first = 0;
  2412. X        secnd = 1;
  2413. X        if (buff[rlen] != SEQMAX)
  2414. X        check = 0;
  2415. X    }
  2416. X
  2417. X    /*
  2418. X     * There we check.
  2419. X     */
  2420. X    if (check) {
  2421. X    if (buff[rlen] != seqc) {
  2422. X        if (state == SKIP_LEADING)
  2423. X        return SKIP_LEADING;
  2424. X        return DECODE_ERROR;
  2425. X    }
  2426. X
  2427. X    if (--seqc < SEQMIN)
  2428. X        seqc = SEQMAX;
  2429. X    }
  2430. X
  2431. X    /*
  2432. X     * output a group of 3 bytes (4 input characters).
  2433. X     * the input chars are pointed to by p, they are to
  2434. X     * be output to file f. blen is used to tell us not to
  2435. X     * output all of them at the end of the file.
  2436. X     */
  2437. X    ut = outl;
  2438. X    n = blen;
  2439. X    bp = &buff[1];
  2440. X    while (--n >= 0) {
  2441. X    *(ut++) = trtbl[*bp] << 2 | trtbl[bp[1]] >> 4;
  2442. X    if (n > 0) {
  2443. X        *(ut++) = (trtbl[bp[1]] << 4) | (trtbl[bp[2]] >> 2);
  2444. X        n--;
  2445. X    }
  2446. X    if (n > 0) {
  2447. X        *(ut++) = trtbl[bp[2]] << 6 | trtbl[bp[3]];
  2448. X        n--;
  2449. X    }
  2450. X    bp += 4;
  2451. X    }
  2452. X    if (fwrite(outl, 1, blen, uu_out) <= 0) {
  2453. X    printf("Error on writing decoded file\n");
  2454. X    return OTHER_ERROR;
  2455. X    }
  2456. X
  2457. X    return DECODE_TEXT;
  2458. X}
  2459. X
  2460. X
  2461. X
  2462. X/*
  2463. X * Install the table in memory for later use.
  2464. X */
  2465. Xstatic inittbls()
  2466. X{
  2467. X    register int i, j;
  2468. X
  2469. X    /*
  2470. X     * Set up the default translation table.
  2471. X     */
  2472. X    for (i = 0; i < ' '; i++)
  2473. X    chtbl[i] = -1;
  2474. X    for (i = ' ', j = 0; i < ' ' + 64; i++, j++)
  2475. X    chtbl[i] = j;
  2476. X    for (i = ' ' + 64; i < MAXCHAR; i++)
  2477. X    chtbl[i] = -1;
  2478. X    chtbl['`'] = chtbl[' '];    /* common mutation */
  2479. X    chtbl['~'] = chtbl['^'];    /* another common mutation */
  2480. X    blank = ' ';
  2481. X    /*
  2482. X     * set up the line length table, to avoid computing lotsa * and / ...
  2483. X     */
  2484. X    cdlen[0] = 1;
  2485. X    for (i = 1, j = 5; i <= NORMLEN; i += 3, j += 4)
  2486. X    cdlen[i] = (cdlen[i + 1] = (cdlen[i + 2] = j));
  2487. X}
  2488. X
  2489. Xstatic gettable(in)
  2490. XFILE *in;
  2491. X{
  2492. X    char buff[LBUFLEN];
  2493. X    register int c, n = 0;
  2494. X    register char *cpt;
  2495. X
  2496. X    for (c = 0; c <= MAXCHAR; c++)
  2497. X    chtbl[c] = -1;
  2498. X
  2499. X    for (;;) {
  2500. X    if (fgets(buff, sizeof buff, in) == Nullch) {
  2501. X        printf("EOF while in translation table.\n");
  2502. X        return -1;
  2503. X    }
  2504. X    numl++;
  2505. X    if (strnEQ(buff, "begin", 5)) {
  2506. X        printf("Incomplete translation table.\n");
  2507. X        return -1;
  2508. X    }
  2509. X    cpt = buff + strlen(buff) - 1;
  2510. X    *cpt = ' ';
  2511. X    while (*cpt == ' ') {
  2512. X        *cpt = 0;
  2513. X        cpt--;
  2514. X    }
  2515. X    cpt = buff;
  2516. X    while (c = *cpt) {
  2517. X        if (chtbl[c] != -1) {
  2518. X        printf("Duplicate char in translation table.\n");
  2519. X        return -1;
  2520. X        }
  2521. X        if (n == 0)
  2522. X        blank = c;
  2523. X        chtbl[c] = n++;
  2524. X        if (n >= 64)
  2525. X        return 0;
  2526. X        cpt++;
  2527. X    }
  2528. X    }
  2529. X}
  2530. X
  2531. END_OF_FILE
  2532.   if test 8069 -ne `wc -c <'uudecode.c'`; then
  2533.     echo shar: \"'uudecode.c'\" unpacked with wrong size!
  2534.   fi
  2535.   # end of 'uudecode.c'
  2536. fi
  2537. echo shar: End of archive 12 \(of 14\).
  2538. cp /dev/null ark12isdone
  2539. MISSING=""
  2540. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  2541.     if test ! -f ark${I}isdone ; then
  2542.     MISSING="${MISSING} ${I}"
  2543.     fi
  2544. done
  2545. if test "${MISSING}" = "" ; then
  2546.     echo You have unpacked all 14 archives.
  2547.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2548. else
  2549.     echo You still must unpack the following archives:
  2550.     echo "        " ${MISSING}
  2551. fi
  2552. exit 0
  2553.